什么时候私有构造函数不是私有构造函数? [英] When is a private constructor not a private constructor?
问题描述
假设我有一个类型,并且想将其默认构造函数设为私有.我写以下内容:
Let's say I have a type and I want to make its default constructor private. I write the following:
class C {
C() = default;
};
int main() {
C c; // error: C::C() is private within this context (g++)
// error: calling a private constructor of class 'C' (clang++)
// error C2248: 'C::C' cannot access private member declared in class 'C' (MSVC)
auto c2 = C(); // error: as above
}
太好了.
但是随后,构造函数却不像我想象的那样私有:
But then, the constructor turns out to not be as private as I thought it was:
class C {
C() = default;
};
int main() {
C c{}; // OK on all compilers
auto c2 = C{}; // OK on all compilers
}
这让我感到非常惊奇,意外和明显不受欢迎的行为.为什么这样可以?
This strikes me as very surprising, unexpected, and explicitly undesired behavior. Why is this OK?
推荐答案
诀窍在C ++ 14 8.4.2/5 [dcl.fct.def.default]中:
The trick is in C++14 8.4.2/5 [dcl.fct.def.default]:
...如果函数是由用户声明的且未明确指定为默认值,则该函数为用户提供的或 在其第一个声明中删除. ...
... A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. ...
这意味着C
的默认构造函数实际上不是不是用户提供的,因为它是在其第一个声明中明确默认的.因此,C
没有用户提供的构造函数,因此根据8.5.1/1 [dcl.init.aggr]:
Which means that C
's default constructor is actually not user-provided, because it was explicitly defaulted on its first declaration. As such, C
has no user-provided constructors and is therefore an aggregate per 8.5.1/1 [dcl.init.aggr]:
aggregate 是一个数组或一个类(第9条),没有用户提供的构造函数(12.1),没有私有的或 受保护的非静态数据成员(条款11),没有基类(条款10)和虚拟函数(10.3).
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
这篇关于什么时候私有构造函数不是私有构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!