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
。