2013-08-01 78 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可以報告錯誤的正確(也是唯一)的地方。由於它是一個專有的工具鏈,因此它們沒有開放的錯誤跟蹤系統。 –