可能重复:
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?
我有以下内容:
#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()中使用前两行而不使用最后两行中的函数样式转换吗?也许使用std :: enable_if解决方案?
答案 0 :(得分:4)
对Foo的任何调用,其参数不完全是std::function<void()>
和std::function<void(int)>
之一,将导致无法解决的重载问题。即使是愚蠢的事情,如Foo(1)
或Foo("abc")
。这是因为std::function
的构造函数是模板化的并且接受任何类型。 std::function<void()>(1)
在实例化时会失败,但在实例化之前会发生重载解析。
所以不,你需要以某种方式提供与其中一个功能的完全匹配。您可以引入其他重载的Foo实例,例如
void Foo(void (*)());
void Foo(void (*)(int));
这将导致更好的匹配,并且不再有歧义。
答案 1 :(得分:3)
可以在C ++ 0x中使用SFINAE使其正常工作。但是,据我所知,MSVC的SFINAE漏洞使它们无法实现,并且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); }
}