【发布时间】:2016-02-10 11:35:13
【问题描述】:
这里到底发生了什么?为什么这是一个错误?
void f(int &&);
int && i = 5;
f(i);
是不是有点反直觉?
我希望i 是一个右值引用,因此能够将它传递给f()。但我得到一个错误;
没有从
int到int &&的已知转换
所以我猜i 不是声明后的右值引用?
这里到底发生了什么?为什么这是一个错误?
void f(int &&);
int && i = 5;
f(i);
是不是有点反直觉?
我希望i 是一个右值引用,因此能够将它传递给f()。但我得到一个错误;
没有从
int到int &&的已知转换
所以我猜i 不是声明后的右值引用?
我明白你为什么感到困惑。要记住的是,只要您有一个变量名,您就有一个 l-value。
所以当你说:
int i = 0; // lvalue (has a name i)
还有
int&& i = 0; // lvalue (has a name i)
那么有什么区别呢?
int&& 只能绑定到一个 r-value 所以:
int n = 0;
int i = n; // legal
但是
int n = 0;
int&& i = n; // BAD!! n is not an r-value
但是
int&& i = 5; // GOOD!! 5 is an r-value
因此,在此示例中,当将 i 传递给 f() 时,您传递的是 l-value,而不是 r-value:
void f(int &&);
int&& i = 5; // i is an l-value
f(i); // won't accept l-value
实际情况比我在这里介绍的要复杂一些。如果您对更全面的解释感兴趣,那么此参考资料非常详尽:http://en.cppreference.com/w/cpp/language/value_category
【讨论】:
this 可以被认为是一个变量(虽然它不是真的),但是this 是一个prvalue。你能想出什么好的方法来解决这个问题,或者它是否真的相关?
is a 和 binds a 之间有一个基本的区别。例如:
void f(int &&);
声明一个接受参数的函数,该参数只能使用对(类型可转换为)int 的右值引用进行初始化。
int && i = 5;
声明一个左值,该左值只能使用对(类型可转换为)int 的右值引用进行初始化。因此,简单来说,
f(i);
尝试将一个对int 的左值引用传递给一个只接受对int 的右值引用的函数。所以它不会编译。
要告诉编译器将左值转换为右值,从而在适用的情况下使用移动构造函数(尽管在int 的情况下不是),您可以使用std::move()。
f(std::move(i));
【讨论】:
std::move 的信息。
i,只能用右值(不是右值引用,右值)初始化。
std::move。如果您想将某些内容作为左值或右值转发,具体取决于其原始值类别,请使用std::forward。写std::forward<int>(i) 而不是std::move(i) 完全没有意义。
i 是一个左值和一个右值引用。
它有名字吗?
是否可寻址?
如果两者的答案都是“是”,那么它就是 L 值。
在这个sn-p中:i有一个名字,i有一个地址(你可以写&i),所以它是一个左值。
f(&&)获取r-value-reference作为参数,所以需要将l-value转为r-value reference,可以通过std::move完成。
f(std::move(i));
【讨论】:
& 应用于它吗?”;但是一元 & 的定义包括它只能应用于左值!