为什么常量双 &&&不适用于左值引用?
Why const double && doesn't work for lvalue reference?
请解释一下它是如何工作的? 为什么双&&适用于左值和右值? 为什么常量双&不为左值工作?
template <typename U>
void function(U& var) {
std::cout << var << std::endl;
}
int main()
{
int var1 = 45;
function(var1);
function(45); //error
}
错误:从类型为"int"函数 (45) 的右值初始化类型为"int&"的非常量引用无效;////////////////////////////////////////////////
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&&"函数(var1);
double &&
不适用于左值。但是,您的代码中没有double &&
,您必须为推导U
U &&
。这是所谓的转发引用的特殊语法。
C++模板推导规则中有一个特殊的规则,它说当参数类型为T&&
时,其中T
是推导类型,并且参数是类型X
的左值,则使用X&
而不是X
进行类型推导。
在你的例子中,这意味着U
被推导出为int&
,所以参数的类型var
从"int& &&
"折叠到int &
。
您可以通过搜索"转发引用"(历史上称为"通用引用")或"完美转发"等术语来了解有关此机制的更多信息。
让我们先总结一下规则。
左值- 可以绑定到左值引用
- 左值不能绑定到右值引用
- 右值可以绑定到常量值的左值引用
- 右值不能绑定到非常量值的左值引用 右值
- 可以绑定到右值引用
- 左值可以绑定到转发引用(并保留其值类别)
- 右值可以绑定到转发引用(并保留其值类别)
第一种情况是对非常量的正确引用,然后
function(var1); // rule#1 -> fine
function(45); // rule#4 -> fail
第二种情况是常量,然后
function(var1); // rule#1 -> fine
function(45); // rule#3 -> fine
第三种情况是转发引用,然后
function(var1); // rule#6 -> fine
function(45); // rule#7 -> fine
第四种情况是右值引用,然后
function(var1); // rule#2 -> fail
function(45); // rule#5 -> fine
值得注意的是右值引用和转发引用之间的区别:
(强调我的)
声明为对同一函数模板的 CV非限定类型模板参数的 rvalue 引用的函数模板的函数参数
在您的示例中,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);
}
附言是的,你应该总是问自己"我真的需要那个右值参考,还是我对那个旧的好左值参考完全没问题?
相关文章:
- 关于类的 Python 文档 - 对C++的引用不正确
- 引用不完整的类类型 - C++
- 类型为 "Bucket&"(未限定的 const 限定)的引用不能使用 "SortedList." 类型的值进行初始化 如何修复此错误?
- 为什么"std::uninitialized_copy"通常取消对未初始化内存的迭代器的引用不是未定
- OpenGL/Glew C++纹理不适用
- 对"列表"的引用不明确,包括头文件
- 为什么引用不能与编译时函数一起使用?
- 对临时对象的Const引用不会延长其生存期
- 为什么要使用引用来获取 *char?当我们使用指针时,不使用引用不是更好吗?
- 强制从函数中推导模板以生成常量引用(如果适用)
- 当我在 windows7 中安装程序时,我指定的字体大小不适用
- 为什么作为返回类型的右值引用不能初始化非常量引用?
- C++字符串引用不能共存
- Constexpr 类采用常量引用不编译
- 为什么对数组的常量左值引用不编译在下面?
- accelerator.cu(8): 错误:属性"managed"在这里不适用?
- 为什么更改指针的引用不会更改其原始值?
- 重值引用不是将类型和类别混合在一起吗?
- 我的模板功能具有通用引用不起作用
- 对类型 'A *' 的非常量左值引用不能绑定到不相关的类型 'std::shared_ptr<A>' 的值