【问题标题】:Template parameter as return type模板参数作为返回类型
【发布时间】:2014-11-05 15:45:00
【问题描述】:

我前段时间偶然发现了这个问题,我终于需要得到一个答案!

问题如下:

#include <iostream>

using namespace std;

template <class FIRST, class SECOND>

FIRST multiply(FIRST a, SECOND b){
    return a * b;
}

int main(){
    int x = 39;
    double y = 38.38;
    cout << multiply(x, y) << endl;
}

在这个 C++ 代码中,我有两个模板参数,函数的返回类型是一个参数的类型。我的问题是返回类型必须是(在这种情况下)与变量 a 相同的类型。我用第三个模板参数尝试了它,但它给了我一个编译错误,谁能给我解释一下?

我不想让它通常是long 或其他东西,我希望返回类型是传递的变量的“最大”类型,这样它也可以与字符和字符串一起使用(对于那些我显然会做其他操作或其他事情,这只是一个例子)。

【问题讨论】:

  • 您可能需要更正您的术语。您有一个带有两个 模板参数的函数模板
  • 谢谢你,因为我还不能说
  • 为什么你希望返回类型像a,在你的例子中是intint * double 给你double 并且,基本上,当从操作结果返回int 时,你会丢失一个分数。

标签: c++ templates return-type


【解决方案1】:

处理此类情况的规范方法是返回从调用的操作结果返回的适当类型:

template <typename FIRST, typename SECOND>
auto multiply(FIRST a, SECOND b) -> decltype(a * b) {
    return a * b;
}

这个用例几乎是添加延迟返回类型的激励示例:操作的结果类型可能完全不可预测。这导致了两个需求:

  1. 需要能够确定decltype(expr) 所做的表达式的类型:它产生expr 声明的类型:当expr 是一个函数调用时,您会查看函数声明,这就是 decltype(expr) 产生的(嗯,其中有一些复杂性)。
  2. 要实际制定expr,经常需要掌握函数参数。因此,引入了一种声明函数的新方法:

    auto 函数名(args) -&gt; return-type

    auto 关键字只是表明函数将使用延迟返回类型function-nameargs 的使用与其他functino 声明中的相同。 return-type 紧随其后的是可以使用参数名称的位置,即-&gt; 之后是 return->type,它通常在前面函数声明。

    换一种说法,如果 return-type 确实 not 引用了参数的名称,那么上面的声明等价于这个声明:

    返回类型 函数名(args)

    如果 return-type 引用了在 args 中引入的名称,您需要处理获取适当类型的对象,例如,使用 std::declval&lt;T&gt;()

【讨论】:

  • 请注意,在 C++14 中您不需要 decltype,模板可以推导出 auto 返回类型。
  • 嗯,谢谢,但我不完全知道 aut 和 decltype 的作用,因为我只有半年的自学 C++ 水平。我可以猜测它的作用和原因,但您介意再详细解释一下吗?
  • 我还不知道那个网站,所以非常感谢!我想这将从现在开始为我省去很多麻烦^^
【解决方案2】:

你可以使用

typename std::common_type<FIRST,SECOND>::type

作为算术表达式的返回类型。

【讨论】:

  • 前面需要typename
  • @Angew:严格来说,typename是告诉编译器它是一个类型。我在和一个人说话……做了一个编辑。
  • 请注意,这不起作用,例如,当FIRSTSECOND 是非方阵时:将matrix&lt;10, 5&gt;matrix&lt;5, 3&gt; 相乘将产生matrix&lt;10, 5&gt;
  • @Dietmar Kühl:不,它没有。但是,作为补偿,它也适用于可变参数标量操作template &lt;typename ... Args&gt; auto multiply(Args ... args) -&gt; typename std::common_type&lt;Args ...&gt;::type,而使用decltype 方法会遇到更多困难。
猜你喜欢
  • 2021-12-17
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多