2016-09-14 79 views
9

,我們使用的是外部庫包含以下明確的構造函數:正在從構造函數二進制兼容刪除'顯式'?

class Chart { 
public: 
    explicit Chart(Chart::Type type, Object *parent); 
    // ... 
}; 

編譯器以下警告抱怨:

chart.h: warning #2305: declaration of 'explicit' constructor 
without a single argument is redundant 

它是二進制兼容的,只是刪除chart.h的explicit關鍵字無需重新編譯庫來避免警告?我的感覺是它是安全的,因爲explicit在這種情況下沒有任何意義。有人可以確認嗎?

+5

關閉愚蠢的警告。 –

+0

我想這是最好的建議:-) – dhaumann

+0

這個警告用於完善pre-C++ 11。如果你的編譯器是pre-C++ 11,那麼你可能會遇到更嚴重的C++ 11代碼問題,所以你可能應該考慮升級。 –

回答

9

你最好由一個國家英里的辦法是關閉該警告該列入的時間,如果你得到了我的意思。 不要破解供應商代碼。

使用explicit多參數構造使得完美的意義C++ 11日起,因爲它可以用來停止隱含括號初始化。 Futhermore標準說,除去explicit必須保留類的佈局,所以你必須假定消除explicit可以打破二進制兼容性。此外,刪除它可能改變做作SFINAE模式的行爲歸結爲構造有可能成爲重新獲得在某些情況下。見http://en.cppreference.com/w/cpp/language/sfinae

2

explicit是有道理的,在大括號初始化的情況下多個參數在C++ 11及以上:

void foo(Chart const &); 

// ... 

// Will only compile without `explicit` 
foo({Chart::Type::pie, myObj}); 

無論是二進制兼容,除去explicit最終取決於你的編譯器,讓你」 d必須在其文檔中找到它。

但是,由於explicit是一個高級語言功能,只有飛行員超負荷分辨率,我不會指望它會破壞兼容性,只要它不會改變某些預先存在的呼叫的最佳匹配,包括從庫本身編譯的任何代碼(模板和/或內聯函數)

這就是說,這是純粹的臨時補丁:根據標準,這樣做甩你直接進入UB領土。引用自n.m.的評論:

擺弄這樣的標題會打破ODR。供應商的二進制文件是用一個特定的類定義編譯的,你的二進制文件是用同一類的不同定義編譯的。這是違法的。無論變化多小,都無關緊要。這些定義必須是逐個令牌一致的句點。

我建議你簡單地沉默警告在這些報頭,在#pragma小號包裝他們,其中包括(或自定義代理服務器報頭,幷包括)。

+0

UV'd。但至於「是否與二進制兼容,最終取決於你的編譯器,所以你必須在它的文檔中找到它。」我們在這裏相互矛盾。我的理解是'explicit'不能影響'struct'佈局。可能是錯誤的。 – Bathsheba

+1

@Bathsheba關於佈局我不知道,但'顯式'可能參與名稱修改,並更改構造函數的過程名稱。我承認,對於我來說,如果沒有閱讀整個標準就沒有保證,但我懷疑有關於這個的一節,所以......安全第一! – Quentin

+5

@Batsheba擺弄這樣的標題會打破ODR。供應商的二進制文件是用一個特定的類定義編譯的,你的二進制文件是用同一類的不同定義編譯的。這是違法的。無論變化多小,都無關緊要。這些定義必須是逐個令牌一致的句點。據我們所知,編譯器可以在符號名稱中包含定義的散列。 –