Что такое назначенный инициализатор?

Я хочу понять, что предоставляют назначенные инициализаторы, которые отличаются от прямой инициализации.

Например:

#include <iostream>

struct Subject{

    int x;
    int y;
    int z;

};

int main()
{ 
    Subject subject_d{.x = 1, .y = 2, .z= 3};
    Subject subject_c{1, 2, 3};

    return 0;
}

Как мы можем декортикировать эти две линии? Для дотошных, в чем разница?


person rekkalmd    schedule 13.07.2020    source источник
comment
@StoryTeller-UnslanderMonica Я подозреваю, что это дословный «перевод» французского глагола «décortiquer», одним из значений которого является тщательный анализ чего-либо.   -  person Borgleader    schedule 13.07.2020
comment
@StoryTeller-UnslanderMonica, если как французское слово -› кожура / корпус ^^ И в этом контексте, как понять   -  person bruno    schedule 13.07.2020
comment
для дотошных ^^   -  person bruno    schedule 13.07.2020
comment
@rekkalmd: я не понимаю вопроса. Вы начинаете с того, что говорите, что понимаете разницу, но потом спрашиваете, в чем разница.   -  person Nicol Bolas    schedule 13.07.2020
comment
Интересный. Обычно быстрый поиск в Интернете не подводит меня так ужасно. Спасибо вам всем.   -  person StoryTeller - Unslander Monica    schedule 13.07.2020
comment
Вы все решили, я ценю!   -  person rekkalmd    schedule 13.07.2020
comment
@ Никол Болас, прости! я новичок в этом термине (назначенный инициализатор), поэтому я спрашиваю, почему он добавлен, есть ли разница с обычным вызовом Subject subject_c{1, 2, 3};?   -  person rekkalmd    schedule 13.07.2020
comment
@rekkalmd Позволяет опустить инициализаторы для любого из полей. Subject subject_c{...}; позволяет опустить только N последних полей.   -  person HolyBlackCat    schedule 13.07.2020


Ответы (3)


В приведенном вами примере нет абсолютно никакой разницы в поведении. Агрегат инициализируется для хранения тех же трех значений. С точки зрения удобочитаемости можно привести аргумент, что назначенная версия инициализатора является более явной с точки зрения того, что происходит. Его также можно использовать для целей документирования. Предполагаемое значение каждого инициализатора (при условии, что мы правильно назвали члены) написано рядом с ним.

Помимо явности в инициализации. Назначенные инициализаторы также хорошо сочетаются с другими функциями C++. Вместо этого подумайте.

struct Subject{
    int x = 0;
    int y = 0;
    int z = 0;
};

Вы могли бы написать

Subject const s { .y = 2 };

Мы используем значение по умолчанию для всех полей, кроме y. А переменная s является константой, потому что мы не хотим, чтобы она изменялась. Это хорошо с точки зрения константной корректности.

Вы можете добиться аналогичного эффекта без назначенных инициализаторов, но это потребовало бы гораздо большего количества шаблонов, если мы хотим, чтобы s оставалось константой, и, возможно, не было бы таким кратким и ясным. Вот вкратце, почему их приятно иметь на языке.

person StoryTeller - Unslander Monica    schedule 13.07.2020

эта строка:

Subject subject_d{.x = 1, .y = 2, .z= 3};

он больше не будет компилироваться, если вы переименуете хотя бы одно из полей или измените их порядок, чтобы эта форма была «безопасной».

но

Subject subject_c{1, 2, 3};

не предполагает имя полей, поэтому, если вы поменяете их порядок, инициализация каждого поля не будет такой же, а будет тихой

person bruno    schedule 13.07.2020

Эти две строки семантически эквивалентны. Один из двух более явный, что может привести к меньшему количеству программных ошибок.

person Stephen M. Webb    schedule 13.07.2020