P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?

When is P1008 ("prohibit aggregates with user-declared constructors") useful in practice?

本文关键字:实践中 什么时候 有用 user-declared prohibit aggregates with P1008 constructors      更新时间:2023-10-16

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/bar/baz代码片段。

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

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

最明显的情况是:

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

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

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