在实践中,P1008(“用用户声明的构造函数禁止聚合”)何时有用?

Vit*_*meo 6 c++ initialization aggregate-initialization c++17 c++20

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

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

int main() {
  X x2{3}; // Compiles in C++17, error in C++20
}
Run Code Online (Sandbox Code Playgroud)

我同意X x2{3};不应该汇编以上声明。然而,证明P1008是我遇到的所有例子都并不现实-他们是纯粹的语法和基本无意义foo/ bar/ baz代码片段。

P1008 在实际中解决什么问题?我很难想象我最终将如何X在一个真实的程序中编写类似上面的内容。

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

Nic*_*las 5

最明显的情况是这样的:

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

X x{};
Run Code Online (Sandbox Code Playgroud)

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

现在,此类类型似乎很愚蠢,但实际上对于实现通过转发功能工作的私有功能很有用。make_shared例如private,即使您使make_shared模板成为朋友,也无法调用声明的构造函数。因此,您改为构造方法public,但要求用户传递只能由具有private访问权限的人员构造的类型的实例。因此X,要么是目标类的成员类型,要么X使目标类成为a friend