2017-01-08 72 views
0

C++ 11給了我們初始化列表。我已經學會了用含蓄詮釋-擴大值在枚舉值運行時,這些不執行收縮轉換,有時會破壞現有的代碼編譯,例如:C++ 11在分配和初始化列表之間的差異

enum COMMAND 
    { 
    COMMAND_WRITE_MISC_CONFIG = 0x70 
    }; 


    struct CommandSettings 
    { 
    quint8 buddy; 
    }; 


    void NarrowingTest::testNarrowing() 
    { 
    quint8 i = 100; 
    CommandSettings test{static_cast<quint8>(COMMAND_WRITE_MISC_CONFIG | i)}; 
    quint8 x = COMMAND_WRITE_MISC_CONFIG | i; 
    QVERIFY(true); 
    }  

test初始化不會沒有編譯演員。

我正在尋找的是x仍在工作的作業初始化背後的基本原理。

+0

你確定以上是有效的c + + 03嗎?我很確定演員也需要在那裏。 – StoryTeller

+1

@StoryTeller帶轉換的版本是C++ 03中的語法錯誤。如果它是'CommandSettings test = {COMMAND_RITE_MISC_CONFIG |我};'但是,這是有效的C++ 03,但是在C++ 11中發生了錯誤,並且可以通過添加一個強制類型使其成爲有效的C++ 11。 – hvd

+0

@StoryTeller不,它是編譯測試應用程序的一部分。只是複製了相關部分(這是一個Qt5.7測試用例,默認情況下啓用C++ 11) – deets

回答

1
CommandSettings test{static_cast<quint8>(COMMAND_WRITE_MISC_CONFIG | i)}; 

這是一個aggregate initialization

從上面的參考:

集合初始化的效果是:

...

如果初始化子句是一個表達式,隱式轉換是 允許作爲每複印通初始化,除非它們正在縮小(因爲 在列表初始化中)(自C++ 11以來)


quint8 x = COMMAND_WRITE_MISC_CONFIG | i; 

這是一個copy initialization

從上面的參考:

副本初始化的效果是:

...

否則(如果T也不其他類型既不是類的類型), 如有必要,使用標準轉換將其他 的值轉換爲cv-unqualified版本的T.

它應該允許縮小轉換,至少爲了向後兼容。

+0

向後兼容性是關鍵。來自C的遺產包含不安全但可行的規則。 C++增加了安全性,但只有使用新的語法。請注意,'= {initializer}'也是有效且安全的 - 實際上它是最安全的,因爲它不允許通過'explicit'函數縮小轉換和轉換的範圍。 – Potatoswatter