请解释一下,它是如何运作的? 为什么要加倍&&适用于左值和右值? 为什么const double&&不适用于左值?
template <typename U>
void function(U& var) {
std::cout << var << std::endl;
}
int main()
{
int var1 = 45;
function(var1);
function(45); //error
}
错误:从'int'函数(45)的rvalue初始化'int&amp;'类型的非const引用无效; ////////////////////////////////////////////////
template <typename U>
void function(const U& var) {
std::cout << var << std::endl;
}
int main()
{
int var1 = 45;
function(var1);
function(45);
}
/////////////////////////////////////////////// /
template <typename U>
void function(U&& var) {
std::cout << var << std::endl;
}
int main()
{
int var1 = 45;
function(var1);
function(45);
}
/////////////////////////////////////////////// /
template <typename U>
void function(const U&& var) {
std::cout << var << std::endl;
}
int main()
{
int var1 = 45;
function(var1); // error
function(45);
}
错误:无法将'int'左值绑定到'const int&amp;&amp;'函数(var1);
答案 0 :(得分:2)
double &&
不适用于左值。但是,您的代码中没有double &&
,对于推断的U &&
,您有U
。这是所谓的转发引用的特殊语法。
C ++模板推导规则中有一条特殊规则,即当参数类型为T&&
时,其中T
是推导类型,且参数是类型为{{1的左值'然后使用X
代替X&
进行类型推导。
在您的情况下,这意味着X
被推断为U
,因此参数int&
的类型会从&#34; var
&#34;进入int& &&
。
您可以通过搜索&#34;转发参考&#34;等条款来了解有关此机制的更多信息。 (历史上称为&#34;通用参考&#34;)或&#34;完美转发。&#34;
答案 1 :(得分:2)
我们首先总结一下规则。
第一种情况是对非const的左值引用,然后是
function(var1); // rule#1 -> fine
function(45); // rule#4 -> fail
第二种情况是lvalue-reference to const,then
function(var1); // rule#1 -> fine
function(45); // rule#3 -> fine
第三种情况是转发参考,然后是
function(var1); // rule#6 -> fine
function(45); // rule#7 -> fine
第四种情况是rvalue-reference,然后是
function(var1); // rule#2 -> fail
function(45); // rule#5 -> fine
值得注意的是rvalue-reference和forwarding-reference:
之间的区别(强调我的)
函数模板的函数参数,声明为对同一函数模板的cv- 非限定类型模板参数的rvalue引用
答案 2 :(得分:0)
在您的示例中,function(var1)
会将var1
用法推断为lvalue
。为了使其与基于rvalue的模板兼容,您必须帮助您的编译器:
template <typename U>
void function(const U&& var) {
std::cout << var << std::endl;
}
int main()
{
int var1 = 45;
function(std::move(var1)); // let convert lvalue to rvalue
function(45);
}
P.S。是的,你应该总是问自己“我真的需要那个左值参考,或者我对那个旧的左右参考完全没问题吗?”