2017-10-21 92 views
7
struct foo 
{ 
    struct bar { 
     ~bar() {}    // no error w/o this line 
    }; 
    bar *data = nullptr;   // no error w/o this line 
    foo() noexcept = default; // no error w/o this line 
}; 

是的,我知道,有一個與正是另一個問題標題相同,但結構稍有不同的問題(涉及noexcept操作並沒有嵌套的類型)。該解決方案建議有(與「在成員函數外部封裝類的定義中需要的默認成員初始值設定項」 - 是我的代碼格式不正確嗎?

foo() noexcept {} 

更換的foo構造函數)改變語義,它沒有必要在這裏:我們這裏有一個更好的答案(因此這個問題不是一個重複)。

編譯:Apple LLVM version 9.0.0 (clang-900.0.37),完整的錯誤信息:

test.cc:44:5: error: default member initializer for 'data' needed within definition of enclosing class 'foo' outside of member functions 
    foo() noexcept = default; 
    ^
test.cc:41:10: note: default member initializer declared here 
    bar* data = nullptr; 
     ^
+1

你可以只declarare析構函數在'bar'和將其定義在課堂外。這種方式編譯。 – skypjack

+0

這是一個鏗鏘蟲。 – Oliv

+0

[「在成員函數外部封裝類的定義中需要的默認成員初始值設定項」的可能重複項是否是我的代碼格式不正確?](https://stackoverflow.com/questions/43819314/default-member-initializer-needed- within-definition-of-enclosing-class-outside) –

回答

1

的問題可以通過違約嵌套類

struct foo 
{ 
    struct bar { 
     ~bar() = default;  // this fixes it 
    }; 
    bar *data = nullptr;   // no error w/o this line 
    foo() noexcept = default; // no error w/o this line 
}; 

然而析構函數來解決,這是我不明白爲什麼/這是否是標準要求的。

+1

增加了'〜bar()= default;'vs'〜bar(){}':'〜bar'的好處,它不是當它是用戶定義的時候(即使是空的)。 –

3

這是一個叮咚的bug。但是有一個簡單的解決方法。

當一個限定爲缺省的一個特殊的成員函數,所述noexcept符只是用於檢查由編譯器生成的默認的特殊構件將noexcept[dcl.sft.dcl.def]

如果函數是明確默認聲明與 noexcept說明符 不會產生相同的 異常規範的隱式聲明(18.4),然後

- 如果該函數在其第一個聲明中顯式默認,則將其定義爲已刪除;

- 否則,該程序是不合格的。

所以,如果你刪除的foo默認構造函數的noexcept sepcifier,你會不會改變語義,foo仍將是無拋出缺省構造:

#include <type_traits> 
struct foo 
    { 
    struct bar { 
    ~bar() {}    // no error w/o this line 
    }; 
    bar *data = nullptr;   // no error w/o this line 
    foo()= default; // foo is noexcept, weither the declarator contains noexcept or not 
    }; 

static_assert(std::is_nothrow_default_constructible<foo>::value); 
+0

如果這是一個已知的叮噹聲,那麼必須有一個可引用的入口到相應的bug庫。你能提供一個鏈接嗎? – Walter

+0

實際上,這是因爲它的行爲不一致而造成的一個叮噹聲錯誤:如果在這兩種情況下默認構造函數都是noexcept,它不應該依賴noexcept說明符。爲什麼我不會檢查或填寫叮噹的錯誤?我的財產概念遵循羅馬式的權利:一個領域屬於農場的領域。所以鏗鏘是谷歌的財產,我不會爲他們免費工作!你可以做到這一點,這不是我的事。 – Oliv

+1

你是多麼的錯。 Clang是開源的,谷歌只是貢獻者之一,其他的則包括蘋果,微軟,AMD,ARM,索尼,英特爾。 – Walter

相關問題