2011-05-31 64 views
7

可能重複:
Why can't my C++ compiler deduce template argument for boost function?
Isn't the template argument (the signature) of std::function part of its type?隱式轉換用的std ::功能

我有以下幾點:

#include <functional> 

void Foo(std::function<void()> ); 
void Foo(std::function<void(int)>); 
void Bar(); 

int main() 
{ 
    Foo(Bar);  // Error: ambiguous 
    Foo([](){}); // Error: ambiguous 

    Foo(std::function<void()>(Bar )); // Ok 
    Foo(std::function<void()>([](){})); // Ok 
} 

我可以讓前兩行在main()工作中沒有函數式的cas t在最後兩行?也許用std :: enable_if解決方案?

回答

4

任何使用不完全是std::function<void()>std::function<void(int)>之一的參數調用Foo將導致無法解析的重載。即使是愚蠢的東西,如Foo(1)Foo("abc")。這是因爲std::function的構造函數是模板化的並且接受任何類型。在實例化時,std::function<void()>(1)會失敗,但重載解析發生在實例化之前。

所以不,你需要提供一個功能,以某種方式精確匹配。您可能會引入美孚的其他重載的情況下,像

void Foo(void (*)()); 
void Foo(void (*)(int)); 

,這將導致更好的匹配和模糊性將不復存在。

3

可以使用SFINAE在C++ 0x中正確工作。但是,據我所知,MSVC的SFINAE bug使得它們無法實現,而GCC的庫實現者似乎沒有注意到,所以這很不幸地不起作用。

我想你也可以嘗試某種make_function。請原諒我的可變模板,這已經有一段時間了。

template<typename T> struct function_proxy { 
    T f; 
    template<typename Ret, typename... T> operator std::enable_if<std::is_same<Ret, decltype(f(std::declval<T>()...))>::value, std::function<Ret(T...)>>::type() { 
     return std::function<Ret(T...)>(f); 
    } 
}; 
template<typename T> function_proxy<T> make_function(T&& t) { 
    return function_proxy { std::forward<T>(t); } 
}