2013-10-07 160 views
1

我注意到boost :: bind與std :: bind不同,它可以在重載函數中使用,當其中一個函數沒有任何參數時。我對嗎?這是記錄的嗎?boost :: bind,std :: bind和重載函數

#include <boost/bind.hpp> 

#include <functional> 
#include <iostream> 

void foo() 
{ 
    std::cout << "::foo() \n"; 
} 

void foo(int) 
{ 
    std::cout << "::foo(int) \n"; 
} 

int main() 
{ 
    boost::bind(foo)(); // Ok 
    boost::bind(foo, 0)(); // Ok 

    // std::bind(foo)(); // Error 
    // std::bind(foo, 0)(); // Error 
} 

#include <boost/bind.hpp> 

#include <functional> 
#include <iostream> 

void foo(int) 
{ 
    std::cout << "::foo(int) \n"; 
} 

void foo(const std::string&) 
{ 
    std::cout << "::foo(const std::string&) \n"; 
} 

int main() 
{ 
    // boost::bind(foo, 0)(); // Error 
    // boost::bind(foo, "str")(); // Error 

    // std::bind(foo, 0)(); // Error 
    // std::bind(foo, "str")(); // Error 
} 

回答

2

我會假設它的實施細節只是一個意外的神器,我不認爲加速提供了有關自動解析正確的過載任何保證。

std::bind是一個用variadic模板實現的C++ 11功能。

boost::bind是爲C++ 03實現的,這意味着它依賴於大量的重載函數模板。

這兩者在實現細節上有很大的不同,因此,我認爲他們的行爲之間的任何差異都是其結果,而不是有意和明確的差異。

Boost文檔僅指出這一點: 「綁定重載函數中的錯誤通常結果,因爲沒有辦法知道哪些超載是爲了約束的嘗試。」

在我的書中,這意味着Boost文檔告訴你這是「未定義的行爲」,無論這是否工作(編譯),甚至選擇正確的過載。

據我所知,你應該總是使用明確的演員陣容(static_cast)來修復你想要選擇的重載的簽名。對於boost::bindstd::bind都是如此,從這個意義上說,兩種實現都是一致的。

2

它在某種程度上記錄爲「接口」 - >「概要」部分,其中列出了過載。正如你可以看到有,升壓的確使用可變參數模板,因此給出的過載時,明確這些:

template<class R> unspecified-2 bind(R (*f)()); 
template<class F, class A1> unspecified-3-1 bind(F f, A1 a1); 
template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1); 

編譯器更喜歡重載版本與空的參數列表對他人,因爲它是一個更好的匹配。不過,我認爲這不是故意的。

1

第一種情況編譯以及在MSVC10既stdboost(因爲MSVC10不支持可變參數模板,所以std::bind同樣實施boost::bind)。

第二種情況不會編譯,因爲bind可以解析具有不同參數的重載,但無法解析僅由參數類型不同的重載。