为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
达令说 2019-10-31 14:13:54
给定以下代码,歧义背后的原因是什么?我可以规避它还是必须保留(烦人的)显式演员表?#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。两者都给我完全相同的歧义。
查看完整描述

3 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

这是一个如何包装std::function一个类的示例,该类检查其构造函数参数的可调用性:


template<typename> struct check_function;

template<typename R, typename... Args>

struct check_function<R(Args...)>: public std::function<R(Args...)> {

    template<typename T,

        class = typename std::enable_if<

            std::is_same<R, void>::value

            || std::is_convertible<

                decltype(std::declval<T>()(std::declval<Args>()...)),

                R>::value>::type>

        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() {

    a(x);

    a(y);

}

请注意,这与函数签名上的重载并不完全相同,因为它将可转换参数(和返回)类型视为等效。对于确切的重载,这应该起作用:


template<typename> struct check_function_exact;

template<typename R, typename... Args>

struct check_function_exact<R(Args...)>: public std::function<R(Args...)> {

    template<typename T,

        class = typename std::enable_if<

            std::is_convertible<T, R(*)(Args...)>::value>::type>

        check_function_exact(T &&t): std::function<R(Args...)>(std::forward<T>(t)) { }

};


查看完整回答
反对 回复 2019-10-31
  • 3 回答
  • 0 关注
  • 706 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信