【发布时间】:2021-10-10 20:06:06
【问题描述】:
请帮我完成这个程序:
struct U {
U(int *) noexcept;
private:
~U() noexcept;
};
struct B {
B();
~B();
U v; //ok
U w{nullptr}; //ok
U u = nullptr; //error
};
这里 struct U 有一个私有析构函数,仅用于证明编译器并未真正调用析构函数并简化代码长度。
而structB只声明了一个默认的构造函数和析构函数,所以编译器不会在这个翻译单元中生成它们。
struct B 也有 3 个字段:v、w 和 u。 v 和 w 字段没有问题,但对于 u 字段,编译器会发出关于 U 的不可访问析构函数的错误:
error: 'U::~U()' is private within this context
13 | U u = nullptr; //error
演示:https://gcc.godbolt.org/z/YooGe9xq6
问题是:
- 如果
B::B()没有在这个翻译单元中编译,为什么要考虑字段默认初始化? - 错误是因为为
u字段的初始化创建了一个临时对象吗? (没有强制复制省略?) - 那么
u和w的情况有什么区别?
【问题讨论】:
-
请注意,强制copy elision 不能发生,因为它要求析构函数在复制发生时可访问。请参阅 this question 了解有关为什么会这样的一些信息。
-
我愿意将此诊断归因于编译器特性。例如,
icc和msvc都拒绝编译代码,即使没有违规行。总体而言,无论U成员如何初始化,B都无法使用。
标签: c++ default-value