2016-02-28 75 views
0

我有一種感覺,這個問題的答案是否定的,但是是否可以初始化某個工會的特定成員?例如以下:初始者,工會的具體成員

#include <cassert> 
#include <Windows.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    auto time = 20090520145024798ull; 

    auto large = ULARGE_INTEGER() = {   
     { time } 
    }; 

    assert(large.QuadPart == time); 

    return 0; 
} 

(Visual Studio的2013中,Windows 10),產生一個編譯器「從‘無符號__int64’到‘DWORD’轉換」,這意味着它會試圖鞋拔的uint64_t中進DWORD。

ULARGE_INTEGER是工會:

typedef union _ULARGE_INTEGER { 
    struct { 
     DWORD LowPart; 
     DWORD HighPart; 
    } u; 
    ULONGLONG QuadPart; 
} ULARGE_INTEGER; 

是什麼標準說一下在這樣的情況下初始化的順序?我希望編譯器能夠看到QuadPart是分配的合適成員。

回答

4

與工會,您可以使用列表初始化,只初始化第一個成員,按[dcl.init.aggr]:

當工會與括號內的初始化初始化,大括號只應包含一個初始化子句 ,該聯合的第一個非靜態數據成員。 [示例:

union u { int a; const char* b; }; 
u a = { 1 }; 
u b = a; 
u c = 1; // error 
u d = { 0, "asdf" }; // error 
u e = { "asdf" }; // error 

末端示例]

所以,在你的榜樣,下面:

ULARGE_INTEGER large{time}; 

將初始化u.LowPart,不QuadPart,不管是什麼各種成員的類型是。

如果你想要做別的,你就必須要明確一下:

ULARGE_INTEGER large; 
large.QuadPart = time; 

或寫,實際上有一個構造更好的union類型。

+0

啊,就是這樣,謝謝巴里。 – Robinson

3

保持簡單:

ULARGE_INTEGER large; 
large.QuadPart = time; 

或者,如果你想使用汽車,在一行中初始化它,使一個小幫手吧?

inline auto MAKE_ULARGE_INTEGER(ULONGLONG t) 
{ 
    ULARGE_INTEGER result; 
    result.QuadPart = t; 
    return result; 
} 

auto large = MAKE_ULARGE_INTEGER(time); 
+0

哦,是的,我知道我當然可以做到這一點。 – Robinson

+0

這是唯一的方法。或者正如我所說的做一個小助手(與我所做的ULARGE_INTEGER的風格相匹配)。你也可以使用自動。 – Jts

+0

每個人和他們的狗似乎都是(ab)使用'auto'作爲一切。這絕對不是應該使用'auto'的情況。在編寫庫代碼時,如果您不知道具體的類型,這會很有幫助。在知道類型時不應該使用它。代碼應該是可讀的,即使您沒有在代碼編輯器中加載它,該代碼編輯器會顯示顯示具體類型的工具提示(例如文檔中的示例代碼,以HTML或本頁發佈)。 – IInspectable