使用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::bind
爲partial application,其中數值是固定的,產生一個boost::function
即需要更少的參數,但調用綁定對象時提供的參數正確數目的某些對象。
以下代碼適用於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:您在前面是正確的。 func0
在第二個例子中也是如此。至少對於我所看到的實現,MSVC++ 2010SP1和g ++ 4.4/Linux來說至少如此。
望着引用Boost文檔,它不是明確的,因爲我想它是安全的,通過額外的參數:
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)
不包含對第一個以外的任何參數的引用,但它仍可以與多個參數一起使用。 任何額外的參數都將被忽略,就像在第三個示例中忽略第一個和第二個參數一樣。 [重點煤礦]
聲明關於額外的參數被忽略是不是明確的,因爲我想說服我,這是在一般情況下正確的。查看TR1,從3.6.3節可以明顯看出,可以調用與bind
返回的可調用對象的參數數目不同,但是目標對象預期的參數數目不同。這是最好的保證嗎?
+1爲完美的第一個問題。我愛你一點點。 –