質問
私は(make_fn()
経由)ファンクタの生成を簡素化しようとしていますそのアリティのメンバ関数のnの(wrap()
経由)前処理のパラメータの。
ファンクタを生成すると、基本的に働いて、今までにのみ明示的にメンバ関数のパラメータ型を指定している。
struct X {};
template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
bool wrap(C* c, X x)
{
return (c->*F)(process<T1>(x));
}
template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(F f) // <- problem here, F is not a type
{
return boost::bind(&wrap<C, T1, F>, _1, _2);
}
このしかし、VC ++およびグラムで++ F
のパラメータの種類としてmake_fn()
は表示されません。私はここで何かを明らかに見逃している必要があり、ややブラインド感じています。
アイデアは、それがこのように動作しなければならないということでした
struct A
{
bool f1(bool) { return true; }
};
void test()
{
A a;
X x;
make_fn(&A::f1)(&a, x);
}
その仕事を作成する方法上の任意のアイデア?
の背景:の
私は、簡略化され、固定されたインターフェースを持って次のようになります:
bool invoke(C* c, const char* const functionName, int argCount, X* args);
Xは、私は、特定のバックエンド型(int型、のstd ::文字列、...)に変換する必要がバリアント型である。
私は名前でルックアップされているファンクタのマップを持っているこれらの呼び出しを処理し、いくつかのインスタンスのメンバ関数へのこれらの呼び出しをマップする。
ラッピングの意図は、手動で変換を避け、代わりに私やthrow
のための変換を行うファンクタを生成することです。私はこのマクロベースのソリューションで作業していますが、そのソリューションは、明示的なタイプとパラメータ数を指定する必要があります。
関数オーバーロード解決を介してIは、メンバ関数シグネチャから暗黙的に正しい変換ファンクタを生成することを望む。
解決
あなたが、私は(あなたの質問にコメントを参照してください)仕事に行くのではありません怖い非型テンプレート引数に変換する関数に渡されるポインタをオンにしようとしているように私には見える。
あなたは何ができるか、関数オブジェクトに関数ポインタを格納することです。以下は、コンパイルに表示されます:
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct X {};
template <class T>
bool process(X) { return true; }
template <class C, class T1, class Func>
struct wrap1
{
typedef bool result_type;
Func f;
wrap1(Func f): f(f) {}
bool operator()(C* c, X x)
{
return (c->*f)(process<T1>(x));
}
};
template<class C, typename T1>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(bool (C::*f)(T1))
{
return boost::bind(wrap1<C, T1, bool (C::*)(T1)>(f), _1, _2);
}
struct A
{
bool f1(bool) { return true; }
};
void test()
{
A a;
X x;
make_fn(&A::f1)(&a, x);
}
それは何か良いとどのようにあなたがラッパーの残りの部分を作成している場合は、しかし、私はわかりません。後者の場合はあなただけの可変長引数テンプレートをサポートコンパイラを取得する可能性があります。 :)