我正在关注复数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编写的。
修改
感谢所有人(甚至是凯特格雷戈里本人)提供答案并清理所有内容。
答案 0 :(得分:32)
因为文字(和一般的rvalues)不能通过非const引用传递(因为如果被调用者可以改变它们就没有意义)。通过值传递或通过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;
}
答案 1 :(得分:4)
33和44都是左值;它们是按值而不是通过引用传递给函数的。编译器无法将这两者转换为期望的类型int &
。使用变量(左值),因为它们可以通过引用传递:
int a = 33, b = 44;
max(a, b); // 44
由于您只是在这里处理基本类型(int
),因此通过引用传递是多余的。按值传递会导致副本,但差异可以忽略不计:
template <class T>
T max(T t1, T t2);
这里我们可以传递rvalues和lvalues。但是 你有机会传入类类型的对象。在这种情况下,建议通过引用传递。
但是对于我们不想复制并且想要左值和右值的情况,我们可以通过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);
}
如果要在原始代码中保留左值引用语法,可以使用此左值填充:
template<typename T>
T& lvalue(T&& t)
{
return t;
}
int main()
{
max(lvalue(1), lvalue(2));
}
答案 2 :(得分:4)
这里的答案最终出现在您未在测试中使用的无关代码中。绝对是我的小max()应该通过值或const-ref,这只是一个脑筋,我会尽快解决。
但是完整的演示代码可以很好地运行。那是因为它包含更多标题,其中一个标题带来了xutility,因此std::max
。这导致我没有注意到我的max
没有被使用。我将使用biggest
这样的名称重做演示,以便再次消除这种情况。在此期间,是的,如果你想通过引用将文字传递给函数,它们需要是const ref。我知道这一点,但是在编写测试工具时却没有想到它,然后在糟糕的代码工作时被愚弄了。我应该更仔细地重新阅读代码:感谢您关注我。 (并且感谢您参加该课程,我希望您发现它有用。)
答案 3 :(得分:3)
您无法将临时值传递为T&
。由于您不更改参数,请使用const T&
代替
BTW,内置max
功能
答案 4 :(得分:3)
整数文字不能作为非const引用传递。此外,您的max
函数可以使用const
引用,因此请适当标记它们:
T max(const T& t1, const T& t2)
答案 5 :(得分:2)
如果您通过引用使用参数定义了函数,则不能使用除变量名称之外的任何参数 - 并且您尝试使用数字。
答案 6 :(得分: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;
}