2012-10-22 274 views
2

我得到了下面的代碼,其中自敗,如果我從變種刪除的boost ::空白警告:編譯器警告::變種

namespace DB 
{ 
struct Value{}; 
struct Container{}; 
} 

typedef boost::variant <boost::blank, DB::Value, DB::Container> CommandData; 

struct Command { 
    explicit Command(CommandData& _data): data(_data){ 
    } 

    CommandData data; 
}; 

int main() 
{ 
    CommandData commandData; 
    Command command(commandData); 
    return 0; 
} 

這是什麼問題?

這裏的警告:

1>: warning C4345: behavior change: an object of POD type constructed with an initializer of the form() will be default-initialized 
1>   c:\boost_1_49_0\boost\variant\variant.hpp(1224) : while compiling class template member function 'boost::variant<T0_,T1,T2>::variant(void)' 
1>   with 
1>   [ 
1>    T0_=boost::blank, 
1>    T1=DB::Value, 
1>    T2=DB::Container 
1>   ] 
1>   c:\code.h(38) : see reference to class template instantiation 'boost::variant<T0_,T1,T2>' being compiled 
1>   with 
1>   [ 
1>    T0_=boost::blank, 
1>    T1=DB::Value, 
1>    T2=DB::Container 
1>   ] 
+0

我刪除了代碼中的省略號。它們在C++ 11中有意義,並且在示例中不鼓勵。還請嘗試提供完整的編譯示例代碼,展示您的問題。在你的情況下,編譯代碼是微不足道的,但你應該儘量減少對儘可能回答你問題的人的摩擦。 – pmr

+0

@pmr根據要求更新了問題! – Baz

+0

我什麼都沒要求。只是告訴你如何獲得更好的答案。無論如何,你也可能希望通過'const'採用'_data',或者甚至直接通過'&&'接受一個包含的值,並將其轉發到變體上。 – pmr

回答

7

該警告相當愚蠢。 It warns that MSVC現在做正確的事情,而不是一些古代版本。您可以用pragma將其關閉。

0

這不是變的,因爲。嘗試把int作爲一個結構成員,而不是variant,並且你會得到相同的警告。問題在於變體默認使用第一個值進行初始化,而boost :: blank是一個特殊類型,用於優化變體行爲。請參閱Boost中的變體文檔

+0

我應該在我的變體中添加什麼類型來表示Command可能沒有與其關聯的數據的想法? – Baz

+0

你是對的。使用boost :: blank。 Bur擺脫結構體中的構造函數,並使用Command作爲POD數據類型或@prm暗示此警告爲 –

+0

但構造函數強制初始化數據成員。 – Baz