6

P1008(“禁止使用用户声明的构造函数进行聚合”已成为 C++20 标准的一部分,以防止在使用聚合初始化时出现意外行为:

struct X {
  int i{42};
  X() = delete;
};

int main() {
  X x2{3}; // Compiles in C++17, error in C++20
}

我同意上述X x2{3};声明不应编译。然而,我遇到的所有证明 P1008 的例子根本不现实——它们纯粹是句法,基本上没有意义//foo代码片段。barbaz

P1008在实践中解决了什么问题?我发现很难想象我最终会如何X在一个真实的程序中写出类似上面的东西。

在 C++17 聚合中删除默认构造函数而不提供其他构造函数来初始化它对我来说似乎是不现实的。

4

1 回答 1

5

最明显的情况是这样的:

struct X
{
private:
    X() = default;
};

X x{};

这不是应该能够在私有可访问上下文之外初始化的类型。但它可以。

现在,这些类型可能看起来很傻,但它们实际上对于实现通过转发函数工作的私有函数很有用。make_shared例如,不能调用声明的构造函数private,即使您将make_shared模板设为朋友也是如此。因此,您创建了构造函数public,但要求用户传递一个类型的实例,该实例只能由具有private访问权限的人构造。所以X要么是目标类的成员类型,要么X使目标类成为friend.

于 2019-11-13T16:00:32.903 回答