boost-bindを使用すると、結果のboost-functionは、バインドされたオブジェクトが予想するよりも多くの引数を受け取ることがあります。概念的:その署名は、それが引数を取らないことを示していてもboost :: bindを使用して、予想よりも多くの引数を渡しても安全ですか?
int func() { return 42; }
boost::function<int (int,int,int)> boundFunc = boost::bind(&func);
int answer = boundFunc(1,2,3);
この場合、func()
は、スタック上の1,2、及び3を受信します。
これは値がより少ない引数を取るが、が正しい数の引数を供給するバインドされたオブジェクトを呼び出すときboost::function
をもたらす特定のオブジェクトのために固定されているpartial applicationためboost::bind
のより典型的な使用とは異なります。
次のコードは、両方のMSVC++ 2010 SP1で機能します。これは、転記される形が縮小されています。元のコードは、Linuxのg ++ 4.4でも動作します。
以下は、C++標準に従って明確に定義されていますか?
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
void func1(int x) { std::cout << "func1(" << x << ")\n"; } // end func1()
void func0() { std::cout << "func0()\n"; } // end func0()
int main(int argc,char* argv[])
{
typedef boost::function<void (int)> OneArgFunc;
OneArgFunc oneArg = boost::bind(&func1,_1);
// here we bind a function that accepts no arguments
OneArgFunc zeroArg = boost::bind(&func0);
oneArg(42);
// here we invoke a function that takes no arguments
// with an argument.
zeroArg(42);
return 0;
} // end main()
は私がなぜzeroArg(42)
作品を理解する:未使用の引数は、呼び出されたルーチンで呼び出すルーチンによってスタックに入れて、単純にアクセスされません。呼び出されたルーチンが戻ると、呼び出し側ルーチンはスタックをクリーンアップします。引数をスタックに置くので、引数を取り除く方法を知っています。
別のアーキテクチャまたはc++コンパイラに移動するとこれが破損しますか?より積極的な最適化はこれを壊すでしょうか?
私は、Boostの文書または標準化文書のいずれかから、より強い声明を探しています。私はいずれかの中で明確な位置を見つけることができませんでした。
デバッガを使用してアセンブリとスタックを調べると、最初の例のfunc
は値1,2と3を受け取らないことがわかります。 2番目の例ではfunc0
についても同様です。これは、少なくとも私が見ている実装、MSVC++ 2010SP1、およびg ++ 4.4/Linuxでは当てはまります。最後の例では、関数オブジェクトがによって生成、という
bind(f, _2, _1)(x, y); // f(y, x)
bind(g, _1, 9, _1)(x); // g(x, 9, x)
bind(g, _3, _3, _3)(x, y, z); // g(z, z, z)
bind(g, _1, _1, _1)(x, y, z); // g(x, x, x)
注:私は、追加の引数を渡すために安全であることを希望として参照ブーストのドキュメントを見て
は、それはのようにはっきりしていません
bind(g, _1, _1, _1)
には、最初の引数以外の引数への参照は含まれていませんが、複数の引数で引き続き使用できます。 3番目の例で最初の引数と2番目の引数が無視されるように、余分な引数は無視されます。 [重点鉱山。]
文の余分な引数については無視されているが、私は、これは一般的なケースでは真実であることを私を説得したいほど曖昧でないではありません。 TR1を見ると、呼び出し可能オブジェクトがbind
から返され、対象オブジェクトが期待する数とは異なる引数で呼び出すことができることが、3.6.3項から明らかです。それは最高の保証が利用可能ですか?
+1は完璧な最初の質問です。私はあなたを少し愛しています。 –