2017-01-08 4 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 | i}; ', хотя это допустимо C++ 03, но сделал ошибку с C++ 11, и можно сделать допустимым C++ 11, добавив приведение. – hvd

+0

@StoryTeller nope, это часть компиляционного тестового приложения. Просто скопировал соответствующую часть (это тестовый файл 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.

Из приведенной выше ссылки:

эффектов инициализации копии является:

...

В противном случае (если ни Т, ни типа других типов классов), стандартные преобразования используются, если необходимо, чтобы преобразовать значение другое в cv-неквалифицированную версию T.

Он должен допускать сокращение конверсий, по меньшей мере, для обратной совместимости.

+0

Обратная совместимость - ключ. Наследие от C содержит небезопасные, но работоспособные правила. C++ добавляет безопасность, но только с новым синтаксисом. Обратите внимание, что '= {initializer}' также действителен и безопасен - на самом деле это самый безопасный, поскольку он запрещает как сужение конверсий, так и преобразование с помощью «явных» функций. – Potatoswatter

 Смежные вопросы

  • Нет связанных вопросов^_^