【问题标题】:C++ Templates ByRef vs. ByValC++ 模板 ByRef 与 ByVal
【发布时间】:2018-03-11 20:55:45
【问题描述】:

我正在学习 C++ 的在线课程 (Pluralsight.com) 并努力练习模板,特别是将实际数字(例如 3)传递给需要 (T& t) 的模板。

讲师编写的代码无法在我的 PC 上编译 - 我相信我理解它为什么无法编译,但想知道它是如何为讲师(谁演示它)编译的,以及您应该如何处理这种情况。

#include "stdafx.h"
#include <iostream>

template <class T>
T myMax(T& t1, T& t2) 
{
    return t1 < t2 ? t2 : t1;
}

int main()
{
    int result = myMax(3, 4);
    return result;
}

编辑: 修正了代码中的拼写错误(来自我在提问之前的实验)。它似乎在https://ideone.com/1cjJUD 中运行,所以我现在不确定为什么它不能为我编译! (感谢@user4581301)

EDIT2 回答后,更改函数名称以避免混淆。应该让任何偶然发现同一件事的人更清楚地提出问题。 https://ideone.com/dZffn6

编译器错误为"C2664 'T max&lt;int&gt;(T &amp;,T &amp;)': cannot convert argument 1 from 'int' to 'int &amp;" 在我看来,这似乎失败了,因为3 是一个实际数字,而不是对存储在某处的数字的引用。声明 int a=3; 并将 a 传递给我的 max 函数可以正常工作。

  1. 我对编译失败的原因是否正确?
  2. 讲师代码如何编译不出错?这在最近的 C++ 版本中是否发生了变化(我相信该类使用 C++03)?
  3. 是否可以编写一个可以传递 ByRef 或 ByVal 的模板?我最终会得到 4 个案例(a,b)吗? (a&, b); (a, b&); (a&, b&) ?

【问题讨论】:

  • @juanchopanza - 抱歉 - 我在复制代码和格式化时犯了一个错误 - 现在应该修复了。
  • @NeilButterworth - 我认为这没有帮助;阅读教科书和学习在线课程一样容易出现这类问题。我现在已经修复了问题中的代码,但我的问题仍然存在。
  • 它选择了错误的最大值 - 去掉 using 指令,你会看到一个错误。
  • 应该是报错!代码错误!
  • 没有。 @Neil 正在解释为什么 GCC 可以吃掉那些糟糕的代码:它不是。它使用的是std::max,而不是max。又一次针对using namespace std; 的罢工

标签: c++ templates byref byval


【解决方案1】:

因为您是按值返回,所以参数没有理由不是const。右值(包括文字和临时对象)与 const 引用兼容。因此,这将是一种无需处理所有可能组合即可修复它的好方法:

template <class T>
T myownmax(T const& t1, T const& t2) 
{
    return t1 < t2 ? t2 : t1;
}

请注意,我已重命名函数以避免与 std::max 产生歧义。 Neil 在评论中提到删除 using namespace std; —— 虽然该行确实触发了问题,但删除它并不是一个完整的解决方案。

特别是,即使没有using namespace std;,代码std::complex&lt;double&gt; a, b; auto c = max(a, b); 仍然会找到std::max,这违背了将函数设为模板以使其适用于任何类型的整个目的!这是“参数依赖查找”的结果。

所以使用不同的名称是最好的选择。

【讨论】:

  • 谢谢 - 这正是我所希望的答案。我明白为什么在这种情况下使用 const refs 是有意义的。
猜你喜欢
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 2015-02-15
  • 2013-03-16
  • 2012-01-21
  • 1970-01-01
  • 2018-06-13
  • 2011-06-21
相关资源
最近更新 更多