【问题标题】:Why can't decltype work with overloaded functions?为什么 decltype 不能与重载函数一起使用?
【发布时间】:2014-04-13 01:24:27
【问题描述】:

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 调用是否足以告诉它应该检查哪些重载?我在这里错过了什么?

【问题讨论】:

  • 我不确定你想通过输出一个类型来完成什么,但你的最后一段代码除此之外还能工作。
  • @chris 这是一段测试代码。使用decltype 的真实代码位在我给它重载函数时失败,我试图查明问题。
  • 你是要查找返回类型还是实际函数的类型?
  • @chris 我很确定代码正在获取函数的类型。代码本身实际上是在一个模板库中,超出了我的技能水平,但它似乎正在获取模板函数的类型。
  • 如果我错了,请纠正我,但我似乎记得decltype通常与declval一起使用,以将declval参数传递给函数以返回类型。

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


【解决方案1】:

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

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

执行TestType&lt;double, double&gt; 将产生int(double, double) 类型。你可以找到一个完整的例子here

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

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

【讨论】:

  • 在 VS 2013 上是否有任何替代方案?示例代码会产生error C2061: syntax error : identifier 'Ts'error C3203: 'TestType' : unspecialized alias template can't be used as a template argument for template parameter '_Ty1', expected a real type 等错误。
  • 我目前手头没有 2013(它可以与网络编译器一起使用,我认为是 2015)。您可以尝试使用带有type typedef 的模板结构。 template&lt;typename... Ts&gt; struct TestType {typedef ... type;};,使用 TestType&lt;int, int&gt;::type
【解决方案2】:

我相信你可能正在寻找std::result_of&lt;&gt;

cppreference 页面。

【讨论】:

  • 要使用result_of,您需要类型。问题是 - 你没有类型,因为没有一种类型。
【解决方案3】:

我找到了另一种方法:使用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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2017-07-03
    • 2022-01-21
    • 1970-01-01
    相关资源
    最近更新 更多