使用聚合初始化初始化基类子对象时复制省略

2024-02-20

在下面的代码中,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(使用前将#替换为@)

使用聚合初始化初始化基类子对象时复制省略 的相关文章

随机推荐