模板函数在传入数字文字时遇到错误,但字符串文字没有
The template function encountered an error when passed in a numeric literal, but string literals didn't
我正在写这段代码
#include <iostream>
#include <string>
template <typename T>
void Print(T& value)
{
std::cout << value << std::endl;
}
int main()
{
Print("Hello");
Print(1);
}
并且在编译时,编译器提示错误“void Print<int>(T &)' : cannot convert argument 1 from 'int' to 'T &'
”。但是 Print("Hello")
没有得到错误。这是为什么?
然后我将 Print()
函数更改为
void Print(T value)
{
std::cout << value << std::endl;
}
成功了。但是我不明白为什么以前的代码不起作用。
1
是一个 rvalue,因此不能绑定到 T&
。不过,它 可以 绑定到 const T&
。
即
void Print(const T& value)
或
void Print(T&& value)
是修复。
案例一
这里我们考虑一下Print(1);
是如何工作的。
在这种情况下,问题 是 1
是一个 rvalue 而您正试图绑定该右值到对非常量 T
(即 T&
)的 左值引用,这是不可能的,因此是错误的。例如你不能有:
void Print(int &value)
{
std::cout << value << std::endl;
}
int main()
{
Print(1);// won't work
}
解决方案
所以要解决你的问题你可以使用左值引用const T
(即const T&
) 可以绑定到右值,如下所示:
template <typename T>
void Print(const T& value)//note the const added here
{
std::cout << value << std::endl;
}
int main()
{
Print(1); //works now
}
或者,您也可以将参数作为对非常量T
(即T&&
)的右值引用。
template <typename T>
void Print(T&& value)//note the && added here
{
std::cout << value << std::endl;
}
int main()
{
Print(1); //this works too
}
案例二
这里我们考虑语句Print("Hello");
在这种情况下,"Hello"
是一个 string literal,类型为 const char [6]
。此外,字符串文字 "Hello"
是一个 lvalue.
而且我们知道我们可以将左值绑定到 对非常量 T
(即 T&
)的左值引用。所以在这种情况下没有错误。另请注意,在这种情况下,T
被推断为 const char [6]
.
备注
在上面的情况 2 (Print("Hello");
) 中,没有类型衰减,因为参数是通过引用而不是值传递的。
因为这个:
test.cpp:45:11: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
45 | Print(1);
| ^
因此将其转换为通用参考:
template <typename T>
void Print( T&& value ) // notice &&, that's a universal reference, not an rvalue ref
{
std::cout << value << std::endl;
}
我正在写这段代码
#include <iostream>
#include <string>
template <typename T>
void Print(T& value)
{
std::cout << value << std::endl;
}
int main()
{
Print("Hello");
Print(1);
}
并且在编译时,编译器提示错误“void Print<int>(T &)' : cannot convert argument 1 from 'int' to 'T &'
”。但是 Print("Hello")
没有得到错误。这是为什么?
然后我将 Print()
函数更改为
void Print(T value)
{
std::cout << value << std::endl;
}
成功了。但是我不明白为什么以前的代码不起作用。
1
是一个 rvalue,因此不能绑定到 T&
。不过,它 可以 绑定到 const T&
。
即
void Print(const T& value)
或
void Print(T&& value)
是修复。
案例一
这里我们考虑一下Print(1);
是如何工作的。
在这种情况下,问题 是 1
是一个 rvalue 而您正试图绑定该右值到对非常量 T
(即 T&
)的 左值引用,这是不可能的,因此是错误的。例如你不能有:
void Print(int &value)
{
std::cout << value << std::endl;
}
int main()
{
Print(1);// won't work
}
解决方案
所以要解决你的问题你可以使用左值引用const T
(即const T&
) 可以绑定到右值,如下所示:
template <typename T>
void Print(const T& value)//note the const added here
{
std::cout << value << std::endl;
}
int main()
{
Print(1); //works now
}
或者,您也可以将参数作为对非常量T
(即T&&
)的右值引用。
template <typename T>
void Print(T&& value)//note the && added here
{
std::cout << value << std::endl;
}
int main()
{
Print(1); //this works too
}
案例二
这里我们考虑语句Print("Hello");
在这种情况下,"Hello"
是一个 string literal,类型为 const char [6]
。此外,字符串文字 "Hello"
是一个 lvalue.
而且我们知道我们可以将左值绑定到 对非常量 T
(即 T&
)的左值引用。所以在这种情况下没有错误。另请注意,在这种情况下,T
被推断为 const char [6]
.
备注
在上面的情况 2 (Print("Hello");
) 中,没有类型衰减,因为参数是通过引用而不是值传递的。
因为这个:
test.cpp:45:11: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
45 | Print(1);
| ^
因此将其转换为通用参考:
template <typename T>
void Print( T&& value ) // notice &&, that's a universal reference, not an rvalue ref
{
std::cout << value << std::endl;
}