【发布时间】:2017-06-19 23:29:40
【问题描述】:
#include <iostream>
#include <string>
using namespace std;
class Wrapper
{
public:
std::string&& get() &&
{
std::cout << "rvalue" << std::endl;
return std::move(str);
}
const std::string& get() const &
{
std::cout << "lvalue" << std::endl;
return str;
}
private:
std::string str;
};
std::string foo()
{
Wrapper wrap;
return wrap.get();
}
std::string bar()
{
Wrapper wrap;
return std::move(wrap.get());
}
std::string fooRvalue()
{
return Wrapper().get();
}
std::string barRvalue()
{
return std::move(Wrapper().get());
}
int main() {
while(1)
{
std::string s = foo();
std::string s2 = bar();
std::string s3 = fooRvalue();
std::string s4 = barRvalue();
}
return 0;
}
const std::string& 和 std::string&& 的返回值在这个用例中是否安全(假设 std::string 是其他一些不可复制的类型)。我认为它不起作用,因为引用应该指向一些超出范围的局部变量,但它似乎工作得很好?我也看过之前使用的 && 语法,我是否正确使用它(我将它限制在 Wrapper 本身是一个右值时)。
当返回引用是安全的时,我只是有点困惑,我认为规则是对象必须比返回的值长,但我以前见过标准库和提升返回引用之类的东西。如果我将他们给我的引用存储在一个变量中(这不是一个引用),那么如果我返回那个存储的变量,一切似乎都可以正常工作。谁能帮我解决一下,给我一些好的规则来遵循。
这是我一直在玩的 ideone,似乎一切正常:http://ideone.com/GyWQF6
【问题讨论】:
-
如果我没记错的话,
for (char c : Wrapper{}.get()) { ... }是不安全的。
标签: c++ c++11 reference c++14 rvalue