17

我正在学习复数 C++ 课程,其中包含以下代码:

#include <iostream>

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

int main()
{
    std::cout << "Max of 33 and 44 is " << max(33, 44) << std::endl;

    return 0;
}

我输入了这段代码,但与课程代码不同,我收到一条错误消息:

C2664: 'max' : cannot convert parameter 1 from 'int' to 'int &'

课程中的代码是用 Visual Studio Express 2010 编写的,而我的代码是用 Visual Studio Ultimate 2010 编写的。


编辑

感谢大家(甚至是 Kate Gregory 本人)提供答案并澄清一切。

4

7 回答 7

33

因为文字(和一般的右值)不能通过非常量引用传递(因为如果被调用者可以更改它们就没有意义了)。通过值或 const 引用传递:

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

或者

template <class T>
T max(T t1, T t2)
{
    return t1 < t2 ? t2 : t1;
}
于 2012-11-25T21:16:49.727 回答
4

33 和 44 都是右值;它们通过值而不是通过引用传递给函数。编译器无法将这两个转换为预期的类型int &。使用变量(左值),因为它们可以通过引用传递:

int a = 33, b = 44;

max(a, b); // 44

由于您在这里 ( int) 仅处理基本类型,因此通过引用传递是多余的。按值传递会导致副本,但差异可以忽略不计:

template <class T>
T max(T t1, T t2);

在这里,我们可以同时传递右值和左值。但是你可能传入一个类类型的对象。在这种情况下,建议通过引用传递。

但是对于我们不想要副本并且想要左值和右值的情况,我们可以通过const引用传递:

template <class T>
T max(T const &t1, T const &t2);

在 C++11 中,您可以通过通用引用传递参数,以便我们可以绑定 glvalues:

template <class T>
T max(T&& t1, T&& t2);

int main()
{
    int a{0}, b{0};

    max(a, b);
    max(1, 2);
}

如果您想在原始代码中保留左值引用语法,可以使用这个左值 shim:

template<typename T>
T& lvalue(T&& t)
{
    return t;
}

int main()
{
    max(lvalue(1), lvalue(2));
}
于 2012-11-25T21:16:38.417 回答
4

这里的答案原来在于您在测试中没有使用的不相关代码。绝对我的小 max() 应该按值或 const-ref 取值,这只是我会尽快修复的脑误。

但完整的演示代码运行良好。那是因为它包含更多标头,其中之一带来了 xutility,因此std::max. 这导致我没有注意到我max没有被使用。我会用一个名字重做演示,biggest以消除这种情况再次发生。同时,是的,如果你想通过引用将文字传递给函数,它们需要是 const ref。我知道这一点,但是在编写测​​试工具时没有想到,然后当糟糕的代码似乎可以工作时就被愚弄了。我应该更仔细地重新阅读代码:感谢您提醒我注意。(感谢您参加这门课程,希望对您有所帮助。)

于 2012-11-25T21:54:04.870 回答
3

您不能将临时值作为T&. 由于您不更改参数,请const T&改用

顺便说一句,有内置max功能

于 2012-11-25T21:16:25.187 回答
3

整数文字不能作为非常量引用传递。此外,您的max函数可以使用const引用,因此请适当地标记它们:

T max(const T& t1, const T& t2)
于 2012-11-25T21:17:39.220 回答
2

如果您通过引用使用参数定义函数,则只能对所述参数使用变量名 - 并且您尝试使用数字。

于 2012-11-25T21:16:25.127 回答
2

小注。您可以使用函数“ max ”的初始代码。尝试将呼叫从 更改max(34, 44)max<const int>(34,44)。有时它可能很有用。

#include <iostream>

template <class T>
T max(T& t1, T& t2)
{
   return t1 < t2 ? t2 : t1;
}
int main()
{
   std::cout << "Max of 33 and 44 is " << max<const int>(33, 44) << std::endl;
   return 0;
}
于 2012-11-28T05:15:07.037 回答