TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.37K subscribers
Post #688 5.53K
Designated initialization
#новичкам

В продолжение предыдущего поста, почему бы нам не поговорить о том, что такое designated initialization в контексте С++ и какие особенности она имеет в языке.

Эта фича С++20, которая позволяет явно указывать поля, которым присваиваются значения, при создании объекта.

struct Person {
std::string name;
std::string surname;
std::string id;
};

struct Item {
std::string name;
double price;
std::string id;
};

struct Order {
Person person;
Item purchase;
std::string pick_up_address;
};


Пусть у нас есть заказ, который состоит из данных о человеке, который заказал товар, и самого заказанного товара. Мы хотим распарсить входящий запрос от клиента и сформировать структуру Order для дальнейшей обработки. Теперь мы можем сделать это очень просто и почти играючи.

Order order{.person = {.name = "Golum",
.surname = "Iz shira",
.id = "666"},
.purchase = {.name = "Precious",
.price = 9999999.9,
.id = "13"},
.pick_up_address = "Mordor"};


То, как мы указываем каждый член структуры и присваиваем ему значение - и есть designated initialization. Собственно пример показывает всю прелесть фичи. Теперь по коду явно видно, каким полям какое значение присваивается. И даже вложенность поддерживается. Это сильно повышает читаемость и понимание происходящего.

Если хотите использовать наследование, то синтаксис такой:

struct Person
{
std::string name;
std::string surname;
unsigned age;
};

struct Employee : Person
{
unsigned salary;
};

Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };


Так как у полей родителького класса нет какого-то имени, то используются просто вложенные скобки.

А еще вы можете пропускать любые поля и они будут инициализированны по умолчанию! Давно не хватало такой возможности:

struct Point{
int x, y, z;
};

Point p{.x = 2, .z = 3}; // y is not mentioned, but it will have value of 0

Хоть y строит в середине, но это не мешает нам не указывать его при создании класса и это поле гарантированно будет равно 0.

Правда у фичи есть определенные ограничения:

👉🏿 Поля должны идти по порядку их объявления в классе. out-of-order инициализация, как в сишке, запрещена. То есть нельзя делать так:

struct Point{
int x, y;
};

Point p{.y = 2, .x = 3}; // not valid in C++!


Почему бы не сделать так же, как в С? Дело в том, что в С нет деструкторов. А в С++ есть. И поля класса инициализируются в порядке их появления в объявлении класса, а уничтожаются - в обратном.

Программист может подумать, что раз я указываю какое-то поле первым в инициализации, то и значение ему будет присвоено в первую очередь. Но это не так. А учитывая, что инициализаторы могут иметь какие-то спецэффекты, например, как-то зависеть друг от друга, это может приводить к путанице.

👉🏿 Структуры должны быть POD типами, то есть вот такими же структурами без каких-либо конструкторов и специальных методов. Объекты с конструкторами должны создаваться через онные, а не напрямую. Ну это собственно просто ограничения аггрегированной инициализации, через которую и реализованы designated инициализаторы.

👉🏿 Если используете designated инициализаторы для одних полей, то нужно в этом же формате задавать значения другим полям. Смешанный формат запрещен:

struct Point{
int x, y;
};

Point p{2, .y = 3}; // Not allowed


Несмотря на все ограничения, они мне кажутся вполне оправданными, а сама фича вообще супергуд. Пользуйтесь, это сильно повысит читаемость кода.

Have a clear intentions. Stay cool.

#cpp20 #cppcore
  • 🔥 34
  • 👍 16
  • ❤ 10
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →