2013-08-01 33 views
0

3尝试使用ICC编译下面的代码返回此错误: 错误#453:受保护函数“A :: A()”(在第10行声明)无法通过“A “指针或对象。继承保护缺省构造函数不可访问

class A 
{ 
protected: 
    constexpr A() = default; 
    ~A() = default; 

    A(const A&) = delete; 
}; 

class B 
    : protected A 
{ 
public: 
    B() = default; 
}; 

int main() 
{ 
    B b; 
} 

我发现3个怪异的办法让它编译:

  • 使得公共
  • 的构造函数删除的
  • 更换缺失的拷贝构造函数“=默认值;”由“{}”在A的Ctor

我的意思是,为什么?..?

谢谢你的答案:)

+0

http://coliru.stacked-crooked.com/view?id=a9cc8a16eaca2659a30defdaa3e68869-f674c1a6d04c632b71a62362c0ccfc51 –

+0

这看起来像一个编译器错误,因为代码是完全有效的,并在其他编译器上编译。如果还没有发生,你可能需要提交一份错误报告。似乎有几个功能涉及混淆编译器足以产生错误。为了完整性,您可以尝试以下方法来缩小bug:** 1 **删除constexpr,** 2 **尝试公共和私有继承,** 3 **将'= default'替换为{ }在B's ctor ** 3b **中显式初始化B的ctor中的A。国际刑事法院的有趣行为:-) –

+0

1,2和3也不编译,但是3b有效。 – ThiSpawn

回答

1

我确认上v13.1.3(Linux)的这种现象。这当然是 编译器错误,如Arne Mertz所说:我发现如果A是 简单地提供了一个在声明时初始化为 的另外无意义的数据成员,则该类编译,例如,

class A 
{ 
protected: 
    constexpr A() = default; 
    ~A() = default; 

    A(const A&) = delete; 

private: 
    char placate_intel_compiler_bug = 0; 
}; 

我不知道你有什么编译器版本,所以不知道 它是否支持非静态数据成员初始化(或者相同 修复会为你工作),但如果这样做那么这是第5个解决方法,你可能会考虑它的意图是无误的。

删除constexpr对错误没有影响。

3种解决方法,你找到了第三个,更换 默认A::A()有一个明确的A::A(){}是唯一一个 一点不惹你的类的理想的公共行为。

Arne Mertz的3b也适用于我,但有一个缺点 把解决方案放在类A以外。

如果在现实世界中,你必须宣告A::A()constexpr然后牢记,对于第3解决方法,如果一个constexpr 构造不default那么-ed的C++标准11§7.1特殊原因.5,第4段, 对构造函数及其类可能会造成代码在维护中更加脆弱。另一个可能加 为您的第五个解决方法。

+0

我在这里报告了这个错误,因为我不知道该怎么做:[link](http://software.intel.com/zh-cn/forums/intel-c-compiler)。我认为数据成员解决方案是最好的保持A :: A()的编译行为。即使它消耗更多的内存,这个不可复制的基类只用于大对象。 – ThiSpawn

+0

该链接是我相信Joe Public可以报告错误的正确(也是唯一)的地方。由于它是一个专有的工具链,因此它们没有开放的错误跟踪系统。 –