为什么一个非平凡的成员需要为同一类中的匿名联合定义构造函数



在下面的代码中 (https://wandbox.org/permlink/j9tN0hQzINa3W7cl(

#include <iostream>
#include <memory>
using std::cout;
using std::endl;
class A {
public:
    A() {
        cout << "A::A()" << endl;
    }
    ~A() {
        cout << "A::~A()" << endl;
    }
};
class B {
public:
    ~B() {}
    void set() {
        new (&a_) A{};
    }
    void destroy() {
        a_.~A();
    }
    union {
        A a_;
    };
    A a2_{}; // (1)
};
int main() {
    auto b = B{};
}

上面代码中的一个不变性是,通过构造和销毁一个 B 类型的实例,如果设置了变体中的元素,有人会调用 destroy(( 来销毁联合中的元素。

为什么 (1( 的存在需要明确定义 B 中匿名联合的析构函数? 链接器在按原样编译时会引发此代码错误

Undefined symbols for architecture x86_64:
  "B::'unnamed'::~()",

这是叮当声中的错误吗?这段代码使用 gcc (https://wandbox.org/permlink/QvdJNWyrtG8gf9EE( 编译得很好

我无法真正重现您描述的确切问题。你用// (1)做的行是否存在,对编译器在我的任何测试中是否接受代码没有任何影响。此外,我没有收到链接器错误,而是收到编译器错误,指出析构函数被定义为已删除。

在这里尝试一下

话虽如此,这似乎确实是一个叮当声中的错误。基于 [class.dtor]\9,B 的析构函数不应调用变体成员的析构函数a_ ...

最新更新