Ответ 1
Когда вы пишете = {0}
, это только явно инициализирует первый член; остальные нулевые инициализируются неявно в соответствии со стандартом, поэтому на первый взгляд кажется, что вы явно инициализировали все члены с 0
, которые вы написали, но вы этого не сделали.
То место, где вы написали 0
, влияет только на первого члена. Поэтому, когда однажды вы изменили его на 1
, думая, что он изменит всех членов, у вас будет ошибка, как здесь. Это вводящий в заблуждение/опасный/глупый/хрупкий код.
По этой причине, без сопроводительного пояснительного комментария, = {0}
не будет проходить проверку кода в моей команде. Вы должны изначально написать:
T t = {};
И теперь, чтобы решить вашу проблему в соответствии с новыми требованиями, вы должны написать:
T t = {1,1,1};
или, если вы не возражаете против своего struct
потенциально теряющего POD-ness, укажите T
конструктор.
Формальная формулировка
[C++11: 8.5.1/2]:
Когда агрегат инициализируется списком инициализаторов, как указано в 8.5.4, элементы списка инициализаторов берутся как инициализаторы для членов агрегата, увеличивая индекс или порядок членов. Каждый член инициализируется копией из соответствующего предложения инициализатора. Если выражение initializer-выражение является выражением, и для преобразования выражения требуется суживающее преобразование (8.5.4), программа плохо сформирована. [..]
[C++11: 8.5.1/6]:
Список инициализаторов плохо сформирован, если число инициализационных-команд превышает число элементов или элементов для инициализации.
[C++11: 8.5.1/7]:
Если в списке меньше элементов-инициализаторов, чем в агрегате, то каждый член, явно не инициализированный, должен быть инициализирован из пустого списка инициализаций (8.5.4).