在下面的代码中,struct B
是一个有碱基的聚合体struct A
, and B
-对象是聚合初始化的B b{ A{} }
:
#include <iostream>
struct A {
A() { std::cout << "A "; }
A(const A&) { std::cout << "Acopy "; }
A(A&&) { std::cout << "Amove "; }
~A() { std::cout << "~A "; }
};
struct B : A { };
int main() {
B b{ A{} };
}
GCC 和 MSVC 执行A
复制省略,打印:
A ~A
当 Clang 创建一个临时对象并移动它时,打印:
A Amove ~A ~A
Demo: https://gcc.godbolt.org/z/nTK76c69v https://gcc.godbolt.org/z/nTK76c69v
同时,如果定义struct A
删除移动/复制构造函数:
struct A {
A() {}
A(const A&) = delete;
A(A&&) = delete;
~A() {}
};
那么 Clang(预期)和 GCC(在复制省略的情况下不是那么预期)都拒绝接受它,但 MSVC 仍然可以接受。演示:https://gcc.godbolt.org/z/GMT6Es1fj https://gcc.godbolt.org/z/GMT6Es1fj
这里允许(甚至强制)复制省略吗?哪个编译器是正确的?
有一个相关问题为什么 RVO 不应用于基类子对象初始化? https://stackoverflow.com/questions/46065704/why-isnt-rvo-applied-to-base-class-subobject-initialization发布于 4 年前,但是
- 这个问题询问聚合初始化的特殊性,这里没有涵盖;
- 正如我们所看到的,在上面的示例中,三分之二的经过测试的现代编译器应用了复制省略。是由于这些编译器中的错误(四年后仍然存在)还是允许它们这样做?
None
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)