从函数返回 const 对象是否会阻止从外部移动构造
Will returning a const object from a function prevent move construction from outside?
给定此函数和函数调用:
std::string GetString() {
std::stringstream sstr;
const auto str = sstr.str();
return str;
}
const auto returnedStr = GetString();
当我宣布str
为常量时,移动结构会被省略吗?
在您的情况下,returnedStr
将从 GetString()
的返回值移动构造,但该返回值将从str
(1( 复制构造。如果str
没有const
,则返回值将从中移动构造。
请注意,在这两种情况下,返回值优化仍然适用,因此编译器仍然可以直接在returnedStr
空间中构造返回值(甚至str
本身(,跳过一个或两个复制/移动构造。这是由 C++11 12.8/31 授予的:
当满足某些条件时,允许实现省略类的复制/移动构造 对象,即使对象的复制/移动构造函数和/或析构函数具有副作用。在这种情况下, 该实现将省略的复制/移动操作的源和目标视为两个不同的 指代同一对象的方式,以及该对象的破坏发生在较晚的时间 当两个对象在没有优化的情况下被销毁时。复制/移动的省略 在以下情况下允许操作,称为复制省略(可以合并到 消除多个副本(:
在具有类返回类型的函数的
return
语句中,当表达式是 具有相同 CV 不合格的非易失性自动对象(函数或 catch 子句参数除外( 类型作为函数返回类型,可以通过构造来省略复制/移动操作 自动对象直接进入函数的返回值。
当尚未绑定到引用 (12.2( 的临时类对象将被复制/移动时 对于具有相同 CV 非限定类型的类对象,可以省略复制/移动操作 将临时对象直接构造到省略的副本/移动的目标中
第一个要点涵盖了返回值构造的省略,另一个项目符号涵盖了将返回值移动到returnedStr
。请注意对"相同的 cv 不合格"类型的要求,这意味着无论 cv 限定符如何,这都有效。
(1(请注意,如果我们谈论的是除std::string
以外的类X
,它提供了一个采用const X&&
的移动构造函数,那么返回值确实是使用该构造函数(无论它可能具有什么语义(构造的移动。
Angew的回答是对的,但谁能记住所有的语言律师规则?
为了帮助我更容易记住它,我写了以下规则,这些规则来自STL自己的嘴。
- 不要将当地人返回为常量 [16]
$ 抑制移动语义
- 按值返回本地时不使用 move完全相同的类型 [16]
如果这样做,将不会使用 NREVO 。
- 不要通过右值引用 (&&( 返回 [16]
$ 除非你真的知道你在做什么。
笔记:
[16] 不要帮助编译器,走向原生 2013,http://www.youtube.com/watch?v=AKtHxKJRwp4
- 如何从具有移动语义的类对象中生成共享指针
- C++编程从外部文本文件定义数组大小
- 如何在 C/C++ 中从外部库调用函数
- OpenGL - 从外部文件绘制点
- C++使用其他命名空间中的符号,而不使它们可从外部访问
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- 从外部文件C++调用函数
- 如何将值从外部传递到结构函数
- 从已移动捕获的 lambda 中重复移动变量
- 我可以有一个从外部不可见但未在标头中定义的静态友元函数吗?
- 如何在 c++ 中将数字从文件移动到数组中
- 从类移动向量(与 2013 编译器相比)
- 从外部更改名称空间变量值(C )
- GTEST链接错误(从GCC 4.X移动到GCC 7.x)
- 可以从外部进程[C /Windows]移动/调整Windows
- 如何从外部CMake设置CMAKE_TRY_COMPILE_TARGET_TYPE
- QT如何从外部C 类中处理按钮式事件
- Qt的GUI线程在从外部对象调用方法时是否会在引擎盖下生成线程?
- 在本地网络中从外部计算机到计算机的连接
- 从函数返回 const 对象是否会阻止从外部移动构造