2016-04-11 15 views
0

プログラマがいくつかの関数FUNC()を呼び出す前後に任意の数のラップを適用できる単純な汎用スマートポインタテンプレートを作成したいと考えています。例えば、 タイマー、ロック、log_start、FUNC()、log_end、ロック解除、タイマーの停止を開始する必要があった場合一般的なC++関数のラッピング

次に、プログラマーが3つのタイプと関数をテンプレートに指定した場所を簡単に書くことができます。コンパイラに残りをさせてください。 私はそれがタイプリストは、演算子オーバーロードと組み合わせる働いた方法と同様の方法で可変引数テンプレートを使用して行うことができる感覚を得る - 次に>

すなわち

class timer {}; // ctor start timer, dtor stop timer 
class locker{}; // ctor lock, dtor unlock 
class logger{}; // ctor lock, dtor unlock 

いくつかのコードをなど

template <typename ...base_class_list> 
class aggregate : public base_class_list... {}; 
using pre_conditions = aggregate<logger, locker, trans>; 

class gadget 
{ 
    auto do_something() -> void; 
}; // gadget 

最後に(書いておきたい部分は一緒に接着する方法は分かりません)

SMART_PTR<pre_conditions, gadget> g; 
g->do_something(); 

Bjarne Stroustrupの「C++メンバー関数呼び出しのラッピング」で説明されている手法を使用すれば、簡単に十分な作業を行えますが、より一般的で洗練されたソリューションがあるのだろうかと思っていました。

+0

具体的な問題を明確にしたり、詳細を追加して必要なものを正確に強調してください。現在書かれているとおり、あなたが求めていることを正確に伝えるのは難しいです。この質問を明らかにするには、[How to Ask](http://stackoverflow.com/help/how-to-ask)ページを参照してください。 – Barry

+1

この質問は、私があなたがやろうとしていることに関連していると信じているMixinsの非常に良い例を参照しています:http://stackoverflow.com/questions/34193264/mixin-and-interface-implementation/34193545#34193545 –

+0

私はあなた2000年以降にいくつかのフレームワークとツールセットが開発された[アスペクト指向プログラミング](https://en.wikipedia.org/wiki/Aspect-oriented_programming#cite_note-22)に取り上げられました。例えば。 [AspectC++](https://en.wikipedia.org/wiki/AspectC%2B%2B)(私はそれを使用していない、私はちょうどグーグルでそれを見つけた)を参照してください。私の知る限りでは、このアイデアはParkPlaceに由来しています。 –

答えて

0

簡単な方法は、ラップにのみ、すべてのoperator()

template <typename T, typename ... Ts> 
class wrapper 
{ 
    ordered_tuple<Ts...> t; // tuple doesn't guaranty order 
    T* obj; 
public: 
    wrapper(T* obj) : obj(obj) {} 

    T* operator ->() 
    { 
     return obj; 
    } 
}; 

template <typename T, typename ... Ts> 
class magic 
{ 
    T obj; 
public: 
    wrapper<T, Ts...> operator ->() 
    { 
     return {&obj}; 
    } 
}; 

Demo

がの取り扱い:

template <typename T, typename ... Ts> 
struct magic 
{ 
    T obj; 

    template <typename ... Us> 
    decltype(auto) operator()(Us...args) 
    { 
     ordered_tuple<Ts...> t; // tuple doesn't guaranty order 
     obj(std::forward<Us>(args)...); 
    } 
}; 

Demo

operator ->をラップするためには、よりトリッキーです10とデフォルト以外のコンストラクタも実行する必要があります。 (そしてより良い名前を見つける)。

+0

パーフェクト、それはまさに私が探していたものです。 – PMcK

+0

それは今ブログに書かれていますhttps://patmckblog.wordpress.com/2016/04/14/a-hidden-gem-overloading-operator/ – PMcK

+0

@PMcK:私は 'std: :tuple'とあなたのクラス 'aggregate'(これは集合体btwではないかもしれません)(これは私が' ordered_tuple'と呼んだ理由です)。 – Jarod42