猿问

std :: function的模板参数(签名)不是其类型的一部分吗?

给定以下代码,歧义背后的原因是什么?我可以规避它还是必须保留(烦人的)显式演员表?


#include <functional>


using namespace std;


int a(const function<int ()>& f)

{

    return f();

}


int a(const function<int (int)>& f)

{

    return f(0);

}


int x() { return 22; }


int y(int) { return 44; }


int main()

{

    a(x);  // Call is ambiguous.

    a(y);  // Call is ambiguous.


    a((function<int ()>)x);    // Works.

    a((function<int (int)>)y); // Works.


    return 0;

}

有趣的是,如果我将a()带有function<int ()>参数的函数注释掉并a(x)在main中调用,由于唯一可用函数之间的类型不匹配x以及参数不正确,编译将正确失败。如果在这种情况下编译器失败,那么当两个函数同时存在时,为什么会有歧义?function<int (int)>a()a()


我已经尝试使用VS2010和g ++ v。4.5。两者都给我完全相同的歧义。


达令说
浏览 707回答 3
3回答

万千封印

这是一个如何包装std::function一个类的示例,该类检查其构造函数参数的可调用性:template<typename> struct check_function;template<typename R, typename... Args>struct check_function<R(Args...)>: public std::function<R(Args...)> {&nbsp; &nbsp; template<typename T,&nbsp; &nbsp; &nbsp; &nbsp; class = typename std::enable_if<&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::is_same<R, void>::value&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || std::is_convertible<&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; decltype(std::declval<T>()(std::declval<Args>()...)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; R>::value>::type>&nbsp; &nbsp; &nbsp; &nbsp; check_function(T &&t): std::function<R(Args...)>(std::forward<T>(t)) { }};像这样使用:int a(check_function<int ()> f) { return f(); }int a(check_function<int (int)> f) { return f(0); }int x() { return 22; }int y(int) { return 44; }int main() {&nbsp; &nbsp; a(x);&nbsp; &nbsp; a(y);}请注意,这与函数签名上的重载并不完全相同,因为它将可转换参数(和返回)类型视为等效。对于确切的重载,这应该起作用:template<typename> struct check_function_exact;template<typename R, typename... Args>struct check_function_exact<R(Args...)>: public std::function<R(Args...)> {&nbsp; &nbsp; template<typename T,&nbsp; &nbsp; &nbsp; &nbsp; class = typename std::enable_if<&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::is_convertible<T, R(*)(Args...)>::value>::type>&nbsp; &nbsp; &nbsp; &nbsp; check_function_exact(T &&t): std::function<R(Args...)>(std::forward<T>(t)) { }};
随时随地看视频慕课网APP
我要回答