C++11私有默认构造函数

21

以下 C++11 代码在我的 GCC 4.8 上成功编译:

struct NonStack
{
private:
  NonStack() = default;
public:
  static NonStack* Create(){
    return new NonStack;
  }
};
NonStack a;

int main() { }

然而,以下内容会导致编译错误:

struct NonStack
{
private:
  NonStack(){}
};

NonStack a; 

int main() { }
为什么第一个能够成功?私有的默认构造函数不应该禁止使用 NonStack a; 创建对象吗?
为什么第一个能够成功?私有的默认构造函数不应该禁止使用 NonStack a; 创建对象吗?

2
你的代码确实可以在gcc4.8上编译,但是4.9会拒绝它(这是应该的)。 - Praetorian
8
如果问题中有一个明确的问题,那么这个问题会更好。 - Jeremy Friesner
你遇到了什么编译错误? - Eric
3
这将防止他的Create()成员函数编译通过。 - Praetorian
@Eric,我在第二个程序中遇到的错误是foo.cc:6:3: error: 'NonStack::NonStack()' is private等。 - M.M
显示剩余3条评论
1个回答

18

这是gcc的bug54812,编译器未能尊重显式默认特殊成员函数的访问限定符。Bug 56429被标记为早期一个的副本,其中包含一个几乎与问题示例相同的测试用例。

解决方法是升级到解决此问题的gcc4.9版本。或者为构造函数创建一个空的函数体,而不是像第二个示例中那样显式地将其默认值设置为default。


3
请注意,该错误链接到核心语言问题1507。这不是GCC中的错误。标准确实曾经说过,由于构造函数是平凡的,因此不会调用构造函数,如果未调用构造函数,则其为“private”的事实不是一个问题。 - user743382
@hvd认为私有的微不足道的构造函数无法访问,但仍然是一个标准中的缺陷,但是gcc的错误报告仍然表明存在错误,因为他们正在将该逻辑应用于无法访问的微不足道的析构函数。答案可以措辞更好,我稍后会进行更新。 - Praetorian
啊,我错过了那个,标准已经有更合适的措辞很久了。也许有趣的是,标准似乎仍然没有禁止删除指向不完整类类型的指针,该类类型具有无法访问的平凡析构函数,只有在析构函数实际上是非平凡的时候才会产生未定义行为。 - user743382
@hvd 终于找到时间更新了这个内容,但现在我不确定我是否同意这是问题1507的一个影响。那个问题主要涉及值初始化,但问题中的示例是默认初始化。N3337中的[dcl.init]/6清楚地说明,如果默认构造函数不可访问,则默认初始化是不合法的。 - Praetorian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接