=默认忽略访问说明符?

Sil*_*nic 16 c++ constructor defaulted-functions c++11

我发现很奇怪,尽管默认构造函数是private(4.8.1 g ++),但下面的程序仍然编译得很好:

 class A{
 private:
     A() = default;
     A(const A&) = default;
 };

 int main(){

     A a;

 }
Run Code Online (Sandbox Code Playgroud)

实际上从标准的8.4.2 [2](N3242)

显式默认函数只有在被隐式声明为constexpr时才可以声明为constexpr.如果在第一次声明中明确违约,

- 它应该是公开的,

..........

默认说明符忽略访问规范的目的究竟是什么?我觉得这可能会导致类设计者不希望用户创建默认值但需要实现中的默认构造函数的接口问题.我想也许是因为默认构造函数是正常的public,所以default复制它的目的 - 但这并不能解释为什么=default复制构造函数不会忽略private规范.

 class A{
 private:
     A() = default;
     A(const A&) = default;
 };

 int main(){

     A a;
     A b(a); //error: constexpr A::A(const A&) is private

 }
Run Code Online (Sandbox Code Playgroud)

实际上我无法从标准中看到它提到明确默认的copy/move构造函数/赋值没有public.

Pra*_*ian 15

这是一个gcc bug.错误57913包含一个几乎与您相同的示例.错误56429包含几个相关错误报告的链接,其中错误54812已在gcc 4.9中修复,这确实拒绝了您的代码.

error: 'constexpr A::A()' is private
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @Silversonic你引用哪个版本的标准?我找不到*它应该是N3337或N4296中的公共*部分 (3认同)
  • @Silversonic N3337是ISO C++ 11标准版(不是免费的)之后发布的第一个草案.理查德史密斯说[这里](http://stackoverflow.com/a/8323351/241631)它只包含与已发布标准的细微编辑差异,因此我转而使用版本,而不是使用发布之前的版本. (2认同)