2013-04-23 107 views
9

我正在玩std :: function和std :: bind的arround,我發現了一些不直觀的東西,我想更好地理解它。瞭解std :: function和std :: bind

例如:

void fun() 
{ 
} 

void hun(std::string) 
{ 
} 

int main() 
{ 

    function<void(int)> g = &fun; //This fails as it should in my understanding. 

    function<void(int)> f = std::bind(fun); //This works for reasons unknown to me  
    function<void(int, std::string)> h = std::bind(hun); //this doesn't work 

return 0; 
} 

怎麼可能到function<void(int)>綁定到一個函數,空隙()。 然後我可以調用f(1)並獲得樂趣()。 我想了解這是如何完成的。 進入微軟Visual Studio 2012的實現這讓我迷失在一堆不可讀的宏。所以我在這裏問這個問題。

+0

我正在使用vs2012 Express版本。 – Alex 2013-04-23 08:50:14

+0

你能推薦這樣的網站嗎? – Alex 2013-04-23 08:52:11

+0

使用_clang_和_g ++ _進行編譯。 +1,有趣的情況。 – soon 2013-04-23 08:52:34

回答

7

如果您不使用參數佔位符(_1,_2,...),則傳遞給從std::bind返回的函數對象的任何參數將被丟棄。隨着:

std::function<void(int)> f = std::bind(fun, std::placeholders::_1); 

我得到一個(長而醜陋)的錯誤預期。

對於有意Standardese人:

§20.8.9.1.2 [func.bind.bind]

template<class F, class... BoundArgs> 
*unspecified* bind(F&& f, BoundArgs&&... bound_args); 

P3返回:轉發調用包裝g與弱的結果類型(20.8.2)。的g(u1, u2, ..., uM)效果應是INVOKE(fd, v1, v2, ..., vN, result_of<FD cv (V1, V2, ..., VN)>::type),其中CV表示CV的g -qualifiers和下面作爲指定v1, v2, ..., vN被測定結合參數的值和類型。的結合參數v1, v2, ..., vN和對應的類別V1, V2, ..., VN取決於從呼叫衍生bind類型TiD和 -qualifiers呼叫包裝gCV如下

P10上的值CV:

  • 如果TiDreference_wrapper<T>,參數是tid.get()和它的類型ViT&;
  • 如果is_bind_expression<TiD>::value的值是true,則參數是tid(std::forward<Uj>(uj)...),其類型Viresult_of<TiD cv (Uj...)>::type;
  • 如果值jis_placeholder<TiD>::value不爲零,則參數爲std::forward<Uj>(uj),其類型爲ViUj&&;
  • 否則,值爲tid,其類型ViTiD cv &
+0

此外,即使std :: function f = std :: bind(fun);編譯。實際上不可能調用f:f();無法編譯。 – 2013-04-23 09:13:17

+1

@PeterR:顯然,因爲'f'的簽名授權一個參數。 :) – Xeo 2013-04-23 09:14:49

6

通過調用生成起作用模板bind可以接受任何數量的額外的參數轉發呼叫包裝;這些將被忽略。 bind表達式的有效元數和最小簽名取決於構造中使用的placeholder以及它們綁定的可調參數。

相關問題