(注: タグからすでに明らかなように、これは厳密に C ++ 03です。 はい、私は知っています、ラムダはこのすべての苦痛を取り除きます(そして新しい種類をもたらすでしょう)が、これは組み込みシステムです、 90年代のOSバージョンで、C ++ 03コンパイラ(GCC4.1.x、BTW)、またはC++コンパイラを持っていてよかったと言われています。C++11の投稿は控えてください。解決策。実際にこする必要はありません。
また、もちろん、なども実際には含まstd::bind()
れていますが、コードにノイズを追加するだけだと思ったので、プレフィックスを編集しました std::function()
std::tr1
tr1
。 )
関数を登録する必要があるサーバーのようなものがいくつかあり、オブジェクトの類似しているがわずかに異なる関数を呼び出すようにそれらを適応させる必要があります。これらの関数には異なる引数リストがあります。std::function
サーバーはそれを「認識」しており、関数を登録しようとすると、テンプレート引数として渡されたマジックタグに応じて、正しい署名(つまり、必要に応じて正しい)を持つ関数のみを受け入れます。
コードのスケッチは次のとおりです。
// this I just use
class server {
public:
template<unsigned int MagicTag>
bool register_call(typename some_traits_type<MagicTag>::func_type);
};
// this needs to be called from the server
class X {
public:
bool foo();
bool bar(std::string&);
bool baz(int);
};
// this is the glue
class Y {
public:
Y(X& x) : x_(x) {
register_call<MAGIC_FOO>(&Y::foo );
register_call<MAGIC_BAZ>(&Y::bar, _1);
register_call<MAGIC_FBZ>(&Y::baz, _1);
}
private:
X& x_;
template<unsigned int MagicTag, typename Function>
bool register_call(Function function) {
somewhere->register_call<MagicTag>(std::bind( function
, this ));
}
template<unsigned int MagicTag, typename Function, typename PlaceHolder1>
bool register_call(Function function, PlaceHolder1 place_holder1) {
somewhere->register_call<MagicTag>(std::bind( function
, this
, place_holder1 ));
}
int foo() {return x_.foo() ? MAGIC_OK : MAGIC_FAILED;}
int bar(std::string& s) {return x_.bar(s) ? MAGIC_OK : MAGIC_FAILED;}
int baz(int i) {return x_.baz(i) ? MAGIC_OK : MAGIC_FAILED;}
};
これは実際には機能しますが、実際にはもっと多くの機能があり、退屈なコピーアンドペーストの努力としてこれを行うと、私の尊厳感が損なわれ、臭いコードが生成されます。これらの関数はすべてまったく同じように機能しますが、唯一の違いは、呼び出す関数と、渡す引数または渡さない引数だけです。これらを1つのパラメーター化された関数に折りたたんで、違いを隠しておくことができますstd::bind()
。これに失敗したので、私は最初に(のように)パラメーターなしですべての関数に対してこれを行うことに決めましたfoo()
。これは圧倒的多数です。
foo()
そのため、 -like関数のすべての呼び出しを、面倒な部分をX
実行する単一の関数を介してルーティングしたいと思いました。Y::call_it
int call_it(std::function<bool()> f) {return f() ? MAGIC_OK : MAGIC_FAILED;}
X
適切な関数を引数としてバインドします。
register_call<MAGIC_FOO>(&X::foo); // note the X!
// (this is wrong)
somewhere->register_call<MagicCode>( std::bind( std::bind( &Y::call_it
, this
, function )
, std::ref(x_) );
明らかに、これは間違っており、これを解決するための他のすべての試みも間違っています。(私は今10週間しか遊んでいstd::bind()
ないので、我慢してください)。std::function
結局、私は、成長した男を涙で倒すことができ、少なくとも1年間は縮小と彼の拡大家族を養うはずの、テンプレート化された内臓からの陽気なエラーメッセージの信じられないほどの迷路に迷いました。
それで、私が完全な欲求不満から自分自身を殺し、私の子供たちを孤児にする前に、どうすればこれを行うことができますか?