此代码无法编译:
class C {};
void foo (C& c) {}
C bar() { return C(); }
int main()
{
foo(bar());
}
Run Code Online (Sandbox Code Playgroud)
编译错误(GCC 4.1.2)符合foo(bar()):
从'C'类型的临时类型初始化'C&'类型的非const引用
当bar()返回一个mutable对象时,它应该编译...
为什么C++不允许上面的代码?
c++ return-value rvalue-reference temporary-objects pass-by-rvalue-reference
我T&&在课堂上偶然发现了它,功能意味着不同的东西.
功能:
template<class T> void f(T&& t){}; // t is R or L-value
...
int i=0;
f(i); // t in f is lvalue
f(42); // t in f is rvalue
Run Code Online (Sandbox Code Playgroud)
在班上:
template<class T>
struct S {
S(T&& t){} // t is only R-value?
};
...
int i;
S<int> ss(i); // compile error - cannot bind lvalue to ‘int&&’
Run Code Online (Sandbox Code Playgroud)
这是否意味着如果我们T&& t在课堂上,t那么只有rvalue?
有人可以指出我可以获得更多相关信息吗?
这是否意味着我需要为L和R值写两个方法重载?
答案
正如Alf的例子所示,t在函数和类中可以是Lvalue或Rvalue.
当我尝试通过引用调用move成员时,编译器会抛出一个错误,但是当我重新定义成员函数以传递值时,它会起作用.
我可以不在我的成员函数中使用引用传递作为右值吗?
#include <iostream>
#include <string>
class Screen{
private:
std::string contents;
using position = std::string::size_type;
position height,width,cursor_position;
public:
Screen() = default;
Screen& move(position&,position&); // Pass by reference
};
Screen& Screen::move(position& row,position& col)
{
(*this).cursor_position = (row * width) + col;
return *this;
}
int main() {
Screen myScreen;
myScreen.move(4,0); // This line gives a compile error
}
Run Code Online (Sandbox Code Playgroud) 将参数作为右值引用传递只是为了清楚表明您将要操作参数是个好主意吗?有点像 const 正确性的反面。
例如,这个函数接受一个字符串向量,以某种方式对其进行操作并返回一个布尔值:
static bool isThisSomething(std::vector<string>&& input1);
Run Code Online (Sandbox Code Playgroud)
现在如果调用者想用左值调用这个函数,他必须使用std::move()并承认这个向量会被弄乱。这应该可以防止意外的副作用。
std::vector<std::string> lvalueVector = {"foo", "bar"};
bool somethingness = isThisSomething(std::move(lvalueVector));
Run Code Online (Sandbox Code Playgroud)
澄清:
这样isThisSomething做的操作只是一些内部逻辑的一部分,对于调用者来说似乎是无稽之谈。