c++ - 如何在函数返回期间将 move 语义与 std::string 一起使用?

标签 c++ c++11 move-semantics

Possible Duplicate:
C++11 rvalues and move semantics confusion

我认为正确的是

std::string GetLine()
{
std::string str;
std::getline(std::cin, str);
return std::move(str);
}

但是在这个链接http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html (检查标题部分从函数返回显式右值引用)

这是 move 语义排名第一的谷歌搜索结果,显示了与

类似的函数签名
int&& GetInt()
{
int x = 0;
// code here
return std::move(x);
}

从我在其他地方读到的 && 表示右值 reference 所以在这种情况下它返回一个对不存在的对象的引用。

那是什么?

(是的,我知道 move 一个 int 并没有真正的好处,但问题是在第一个函数中是否使用 std::string 或 std::string&& 的返回类型。如果这对所有人都应该这样做类型。)

最佳答案

您绝对正确,int&& GetInt() 示例是错误的,并且正在返回对已销毁对象的引用。但是,除非我错过了它,否则您发布的链接实际上并没有显示任何返回对 local 变量的引用的代码。相反,我看到一个对 global 变量的引用被返回,这没关系。

返回时如何使用 move 语义:

std::string func()
{
    std::string rv;
    /* ... */
    return rv;
}

在返回对象时,通常不应使用 std::move()。这样做的原因是,在 RVO 可能发生的任何时候都已经隐式允许 move ,并且使用 std::move() 将抑制 RVO。所以使用 std::move() 永远不会比仅仅正常返回更好,而且通常会更糟。


同样,使用 std::move() 可能比简单地命名要返回的变量更糟糕,因为它抑制了返回值优化。返回值优化允许将对象返回给调用者,而无需复制该对象

in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value

— [class.copy] 12.8/31

但是使用 std::move() 可以防止返回表达式成为您要返回的对象的名称。相反,表达式更复杂,语言不再允许对其进行特殊处理。

仅仅命名对象并不比使用 std::move() 更糟糕的原因是因为有另一个规则说表达式已经可以被视为右值而不需要 std: :move().

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.

关于c++ - 如何在函数返回期间将 move 语义与 std::string 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12011426/

相关文章:

c++ - move 语义和运算符重载

c++ - 候选模板被忽略 : substitution failure(error with clang but not g++)

c++ - 使用 void* 时如何不损坏地获取数据?

c++ - 构造函数和高级异常抛出 C++

c++ - 那里有 C++0x 的实现吗?

c++ - std::random_device 加密安全吗?

c++ - 根据标准,这些编译器中的哪个有错误?

rust - 为什么 Rust 不允许在一种类型上复制和删除特征?

c++ - 编写 HugeInteger 类

c++ - 为具有 std::thread 成员的类 move 构造函数