无法推论作为函数的模板参数 [英] Cannot deduce template argument that is a function

查看:80
本文介绍了无法推论作为函数的模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

应该可以,因为我受到限制-仅适用于返回 int 的函数。

It should be possible because I am restricting it - only for functions that return an 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个重载。当然,它可以从 5 推导出 Args ... ,但是 foo的类型仍然不可推论,因为编译器在进行类型推导时不知道选择哪个重载。

The compiler tries to deduce the type of foo, but there are 2 overloads. Of course, it can deduce Args... from 5, but the type of foo is still non-deducible, since the compiler doesn't know which overload to pick when doing the type deduction.

请注意,编译器需要知道类型函数签名中的 F 的位置,即在这里,所以SFINAE发挥了魔力:

Note that the compiler needs to know the type of F in the signature of the function, i.e. here, so SFINAE do its magic:

is_same<
    typename result_of<F(Args...)>::type,
    int
>::value,

绝对没有办法从 proxy(foo,5正确推断出 F 的类型)调用,因此SFINAE无法启动。作为一个旁注,请注意C ++不能仅基于返回类型重载。因此,您将无法仅根据返回类型来区分具有相同名称的两个函数。您将需要某种方式来强制进行参数匹配,以使SFINAE消除非候选的重载。

There is absolutely no way for it to correctly deduce the type of F from the proxy(foo, 5) call, so SFINAE cannot kick in. As a side note, remark that C++ cannot overload based on the return type only. So you won't be able to differentiate two functions with the same name based on the return type alone. You'll need somehow to force a parameter matching which will SFINAE out the non-candidate overloads.

与之相关的内容:推导出独立函数的返回类型

并从标准中引用相关内容,强调我的观点(感谢@TC指出):

And a relevant quote from the standard, emphasize mine (thanks to @T.C. for pointing it out):

14.8.2.1通过函数调用[temp.deduct.call] /(6.2)推导模板参数


(6)当P是函数类型,指向函数类型的指针或指向成员函数类型的指针时:

(6) When P is a function type, pointer to function type, or pointer to member function type:


  • (6.1 )如果参数是包含一个或多个函数模板的重载集,则该参数将被视为非推论上下文。

  • (6.1) If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.

(6.2)如果参数是一个重载集合(不包含函数
模板),则尝试使用该集合中的每个
成员尝试推论参数。如果仅对重载
集合成员之一进行扣除成功,则将该成员用作
扣除的参数值。 如果对
重载集合的多个成员成功进行推论,则该参数将被视为非推论上下文。

这篇关于无法推论作为函数的模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆