【问题标题】:=default ignores access specifier?=默认忽略访问说明符?
【发布时间】:2016-01-15 18:36:29
【问题描述】:

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

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

 int main(){

     A a;

 }

其实从标准(N3242)的8.4.2[2]开始

只有当它被隐式声明为 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

 }

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

【问题讨论】:

    标签: c++ c++11 constructor defaulted-functions


    【解决方案1】:

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

    error: 'constexpr A::A()' is private
    

    Live demo

    【讨论】:

    • 好的,谢谢。我想我误解了标准中的引用。它完全特定于 constexpr 声明函数的上下文。
    • @Silversonic 您引用的是哪个版本的标准?我在 N3337 或 N4296 中找不到 it shall be public 部分
    • 我在看 N3242。如果我使用 C++11,我认为这是最好的选择?我应该换成 N3337 吗?
    • @Silversonic N3337 是 ISO C++11 标准版(不是免费的)之后发布的第一个草案。 Richard Smith 说 here 它只包含与已发布标准的细微编辑差异,所以我会切换到该版本,而不是使用发布前的版本。
    • @Silversonic Here's 导致您引用的措辞发生变化的问题
    猜你喜欢
    • 2011-06-15
    • 2013-12-25
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    相关资源
    最近更新 更多