返回 *&object 时是否允许复制/移动省略?
Is copy/move elision allowed when returning *&object?
看看这段代码:
#include <stdio.h>
struct Foo {
Foo() { }
Foo(const Foo &) { printf("copyn"); }
Foo(Foo &&) { printf("moven"); }
};
Foo getFoo() {
Foo f;
return *&f;
}
int main() {
getFoo();
}
C++14 标准说 (12.8/31( 复制/移动省略允许:
在具有类返回类型的函数的 return 语句中,当 表达式是非易失性自动对象的名称(除了 函数或捕获子句参数(具有相同的 cv- 非限定条件 类型作为函数返回类型,复制/移动操作可以是 通过将自动对象直接构造到 函数的返回值
在我的示例中,返回表达式不是一个名称,所以我认为不允许使用省略。
我已经检查了GCC/clang/MSVC,虽然clang/MSVC没有复制,但GCC有。海湾合作委员会是否违反了这里的标准?
首先,"as-if"规则在这里不适用,因为复制和移动构造函数有副作用(它们执行 IO(。 因此,GCC 不能省略该标题下的副本/移动。
一目了然,我看不到任何其他允许省略的措辞,所以我认为这是 GCC 中的一个错误。 另一方面,我非常希望标准能够扩大复制/移动省略的范围以包括这种情况。 (在您提供的最小示例中,我看不出它如何导致问题 - 我假设您有一个大示例。
相关文章:
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- std::元组分配和复制/移动异常保证
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- 在临时将成员带出时省略复制/移动
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- 默认复制/移动构造函数时 GDB 中的奇怪行为
- 返回 *&object 时是否允许复制/移动省略?
- 删除复制构造函数是否也会删除默认的复制/移动运算符?
- 用于删除复制/移动分配运算符的有效签名
- 复制 elision/RVO 会导致从同一对象复制/移动吗?
- 意外缺少隐式声明的复制/移动构造函数
- 是否可以传递具有捕获的不可复制(移动)值的 lambda
- CRTP 和复制/移动赋值/构造函数继承
- C++复制/移动构造函数和赋值运算符
- 覆盖复制/移动分配超载时,我是否需要删除当前的成员数据
- 为什么编译器在有模板构造函数时生成复制/移动构造函数
- C++:使用引用和值解压缩元组,而无需复制/移动太多
- 从C++中的基类继承复制/移动构造函数作为构造函数
- 初始化 std::数组而不复制/移动元素
- 是否允许复制/移动省略使使用已删除函数的程序格式正确?