【问题标题】:Getting return type of an overloaded member function获取重载成员函数的返回类型
【发布时间】:2015-01-15 17:13:21
【问题描述】:

我正在尝试确定重载成员函数的返回类型,以便稍后在我的函数模板中使用该类型(参见下面的示例)。无法弄清楚如何使用 C++11 模板机制来做到这一点(不修改下面代码中 struct A 和 B 的定义)。这是否可行(一般在 C++11 中,特别是在 MSVS2013 中)以及如何实现?

struct A{};
struct B{};

struct X
{
    double f(A&);
    int* f(B&);
};

template<typename T, typename R = /*??? what X::f(T) returns ???*/>
R ff(T& arg)
{
    X x;
    R r = x.f(arg); // preferably if I can create local variables of type R here
    return r;
}

int main()
{
    A a; ff(a);
    B b; ff(b);
}

【问题讨论】:

标签: c++ templates overloading return-type


【解决方案1】:

您可以为此使用decltype(),使用std::declval 来模拟创建方法调用表达式所需的类型的值:

typename R = decltype(std::declval<X>().f(std::declval<T&>()))

Here is a demo,输出R的类型ID;您可以看到它分别正确地推导出了ff(a)ff(b)doubleint *


附注:模板函数的整个主体可以简化为return X().f(arg);

【讨论】:

  • 很好的答案,你能解释一下你最后的评论吗?为什么我们需要X::f() const
  • @vsoftco 我弄错了;他们重载不必是const。有时我对临时对象感到困惑:因为它们只能绑定到 const 引用,所以我偶尔会不小心将临时对象本身视为 const,但事实并非如此。
  • 我特别没有使用 return X().f(arg) 来排除使用 auto 作为 ff() (C++14) 上的返回类型作为可能的解决方案(它不允许创建本地R 类型的变量,在 MSVS2013 中不起作用)。
  • @PowerGamer 但是您仍然可以在没有R 模板参数可用的情况下创建局部变量:auto r = x.f(arg);。 :) 如果您不能使用 C++14 功能,您可以在问题中这样说,而不是编写人为的代码。
  • 我确实提到我在我的问题中寻找 C++11 解决方案,至于你是正确的局部变量。
【解决方案2】:

你也可以像这样使用 C++14 自动返回类型推导:

template<typename T>
auto ff(T& arg)
{
    X x;
    auto r = x.f(arg);
    return r;
}

【讨论】:

  • 最佳解决方案 - 但面向未来。目前MSVS2013不支持此功能,仅在尚未发布的MSVS2015中添加支持。
  • @PowerGamer 对于某些用户来说,未来已经到来(例如,如果他们使用 clang,则自 2013 年 12 月起就可以使用)。也许他们中的一些人有同样的问题并以这种方式找到这个问题,但没有你的限制。这会对他们有所帮助,因此我的回答很有用。
【解决方案3】:

在 C++11 中,可以使用后期返回类型:

template <typename T>
auto ff(T&& arg) -> decltype(std::declval<X>().f(arg))
{
    return X().f(arg);
}

在 C++14 中,您甚至可以省略后期返回类型,让编译器自行确定一切,就像 Baum mit Augen 的回答一样。

编辑:使后期返回类型适用于非默认可构造类型X

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多