为什么decltype无法使用重载函数?

时间:2014-03-10 03:45:45

标签: c++ c++11 overloading decltype

如果您正在调用它的函数被重载,则

decltype会失败,如下代码所示:

#include <iostream>

int test(double x, double y);
double test(int x, int y);
char test(char x, int y);

int main()
{
  std::cout << decltype(test) << std::endl;

  return 0;
}

结果:

error: decltype cannot resolve address of overloaded function

我理解这是因为decltype无法确定您尝试获取哪种类型的函数。但是为什么没有另一种方法可以让这项工作完成,如下所示:

std::cout << decltype(test(double, double)) << std::endl;

或者这个:

double x = 5, y = 2;
std::cout << decltype(test(x, y)) << std::endl;

由于函数不能简单地基于返回类型重载,不会将数据类型或实际变量传递给decltype调用足以告诉它应该检查哪些重载?我在这里缺少什么?

3 个答案:

答案 0 :(得分:19)

要根据您传递的参数类型确定函数的类型,您可以使用decltype“构建”返回类型,并使用这些类型“调用”它,然后添加参数列表将整个类型拼凑在一起。

template<typename... Ts>
using TestType = decltype(test(std::declval<Ts>()...))(Ts...);

执行TestType<double, double>会产生int(double, double)类型。您可以找到完整的示例here

或者,您可能会发现尾随返回类型语法更具可读性:

template<typename... Ts>
using TestType = auto(Ts...) -> decltype(test(std::declval<Ts>()...));

答案 1 :(得分:0)

我相信您可能正在寻找std::result_of<>

cppreference页。

答案 2 :(得分:0)

我发现了另一种方法:使用std::declval生成伪造的对象,然后使用decltype

#include <type_traits>
#include <functional>
int myfunc(int a)
{
    return a;
}
float myfunc(float a)
{
    return a;
}

int main()
{
    decltype(myfunc(std::declval<float>())) a;  // return type
    std::function<decltype(a)(float)> fun;      // function type
    return 0;
}