为什么不能为F推导proxy()

这应该是可能的,因为我限制了它-仅用于返回int的函数。

#include <utility>
#include <iostream>
#include <type_traits>
using namespace std;

int foo(int bar) {
    cout << "int" << endl;
    return 2;
}

float foo(float bar) {
    cout << "float" << endl;
    return 1;
}

template <typename F, typename... Args>
typename enable_if<
    is_same<
        typename result_of<F(Args...)>::type,
        int
        >::value,
    typename result_of<F(Args...)>::type
    >::type
proxy(F func, Args&&... args) {
    return func(forward<Args>(args)...);
}

int main() {
    proxy(foo, 5);
}

这是错误:
b.cpp:29:17: error: no matching function for call to 'proxy(<unresolved overloaded function type>, int)'
b.cpp:24:1: note:   template argument deduction/substitution failed:
b.cpp:29:17: note:   couldn't deduce template parameter 'F'

最佳答案

问题是这样的:

proxy(foo, 5);
编译器尝试推断foo的类型,但是有2个重载。当然,它可以从Args...推导5,但是foo的类型仍然不可推导,因为编译器在进行类型推导时不知道选择哪个重载。
请注意,编译器需要知道函数签名中F的类型,即此处,因此SFINAE可以发挥其魔力:
is_same<
    typename result_of<F(Args...)>::type,
    int
>::value,
绝对没有办法从F调用中正确推断出proxy(foo, 5)的类型,因此SFINAE无法启动。作为补充,请注意,C++不能仅基于返回类型进行重载。因此,您将无法仅基于返回类型来区分具有相同名称的两个函数。您将需要某种方式来强制进行参数匹配,这将SFINAE排除掉非候选的重载。
某种程度上相关:Deducing the return type of a standalone function
并在标准中引用了相关的引言,请强调我的(感谢@ T.C。指出):
14.8.2.1从函数调用[temp.deduct.call]/(6.2)推导模板参数

关于c++ - 无法推论作为函数的模板参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30623939/

10-11 22:48
查看更多