2011-10-18 12 views
1

C++で汎用ラッパーを作成しようとしています。ここで私はこれまでに書かれたものです:汎用ラッパーC++

例えば、使用してインスタンス化することができる
//primary template 
template<typename T> 
class function 
{ 
}; 
//partially specialized template 

template<typename T, typename U, typename V> 
class wrapper<T(U,V)> 
{ 
private: 
    //typedef pointer to function 
    typedef T (*pfn)(U,V); 
    pfn f; 

public: 

    wrapper(pfn func):f(func) 
    { 
    }; 

    T operator()(U a, V b) 
    { 
    return f(a,b); 
    } 
}; 

wrapper<double(double, double)> someWrapper(&someFunction); 
どのように誰かがの面で正しい方向に私を指すことができれば、私は思っていた

次の方法でインスタンス化できるようにラッパーテンプレートを変更してください。

wrapper<double(double, double)> somewrapper(&someClass, &someClass::someFunction) 
wrapper<double(someClass*, double)> somewrapper(&someClass::someFunction) 

私はこの点で助けていただきありがとうございます。

+5

'std :: function'の何が問題になっていますか? –

+0

BoostはすでにBoost.Functionにあります:http://www.boost.org/doc/libs/1_47_0/doc/html/function.html – Dani

+0

http://loki-lib.sourceforge.net/ –

答えて

2

代わりにstd::functionを使用するか、コンパイラにTR1がまだない場合はBoostの実装を使用してください。このような

template<typename T, typename C, typename U, typename V> 
class wrapper<T (C::*)(U,V)> 
{ 
private: 
    //typedef pointer to member-function 
    typedef T (C::*pfn)(U,V); 
    pfn f; 

public: 

    wrapper(pfn func):f(func) 
    { 
    }; 

    T operator()(C c, U a, V b) 
    { 
    return (c.*f)(a,b); 
    } 
}; 

とそのインスタンス化します:それは、このメンバ関数へのポインターを探している専門である、と述べた

wrapper< double(someClass::*)(double, double) > somewrapper; 

あなたが与えた最初のインスタンス化は不可能ではないが、それは大規模なを必要としますクラス型をコンストラクタ引数から導き出すことができないので、それを動作させるための型消去の量。

wrapper<double(double, double)> somewrapper(&someClass, &someClass::someFunction) 

メンバ関数へのポインタでインスタンス化したいと仮定して、私のサンプルコードを少し修正して、2番目のコードを修正することができます。

wrapper<double(someClass*, double)> somewrapper(&someClass::someFunction) 

あなたは、単一のラッパーの定義は、互換性のある引数を持つ自由とメンバー関数の両方に使用できるようにしたいと仮定すると、あなたは再びそれを動作させるためにいくつかのタイプの消去を必要とします。 Boost.Functionの実装では、実際にはvirtualコールを避けるために別の手法が使用されます。

+0

ご返信ありがとうございます。クラスの型がテンプレートパラメータとして渡されたのと同様の実装を作成しましたが、あなたが言ったように、これらのすべてのシナリオをカバーする単一のラッパーを記述できるかどうかを検討していました。それは私がそうすることは自明ではないようです!私はタイプ消去を調べるでしょう、私はそれを認識していませんでした。 – Omar

2

プログラミングや学習の練習としてこれをやっているのなら、問題ありませんが、存在し、徹底的にテストされている多くの実行可能な選択肢があります。 C++ 11を使用している場合はstd::function、そうでない場合はboost::functionboost::bindがあります。

今、これは学習の練習であると仮定すると、異なる数のパラメータと戻り値の数ごとにラッパーのバージョンを作成する必要があります。また、関数がクラスメンバーであるケースをカバーする必要があります。また、Functorクラスを扱っているときに対処したい場合もあります。

これはたくさんの仕事であり、コーナーケースがたくさんあり、既に存在するものを複製するだけで十分です。

+0

あなたの答えをありがとう。はい、あなたがうまくいったように、これは私のための学習の練習です。そこで、私はこれらの実装を見て、どのように動作するかを見ていきます。 – Omar