1

我正在学习 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<int>(T &,T &)': cannot convert argument 1 from 'int' to 'int &" 在我看来它失败了,因为3实际数字不是对存储在某处的数字的引用。声明int a=3;并传递a给我的 max 函数可以正常工作。

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

1 回答 1

3

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

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

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

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

因此,使用不同的名称是最好的选择。

于 2017-09-29T22:27:57.577 回答