TGViewer
this->notes. this->notes. @thisnotes · 4.51K subscribers
Post #211 1.68K
#cpp

Инициализация 2/2.

Непонятно что делать с этой инфой. Давайте посмотрим на пару примеров, которые помогут сделать выводы. Самый простой:

int m();


Вот я хочу инициализировать переменную m по месту. Но, учитывая most vexing parse, это у вас не переменная, а объявление функции. Всё сломалось. Или гораздо более стрёмный кейс:

vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());

Fuck. Это тоже объявление функции (оно скомпилируется и вы получите ошибку в совсем другом месте!). Оставим разбор этого выражения читателю.

Из забавного (если конечно больно можно считать за смешно) следующие кейсы:

int i(1, 2);
int i = (1, 2);
int i = int(1, 2);
auto i(1, 2);
auto i = (1, 2);
auto i = int(7, 9);


Будет ли первое компилироваться? Конечно же нет. Наверное тогда и второе? Ошибка. Второе это оператор запятая, потому всё корректно. Третье, четвёртое и шестое (по аналогии с 3м), очевидно 🎧, тоже CE. Пятое по аналогии со вторым OK.

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

Из интересного ещё следующий момент. В C++11 следующая запись означала std::initializer_list<int>{1}:

auto i{1};

Однако в C++14 семантику подобного изменили, где это стало int{1}.

auto i = {1};


А что же тут? Это без сомнений init_list. Т.е. вы меняете тип объекта при инициализации с помощью =. Конечно интуитивно это вроде понятно, но кринж🥴, не правда ли? Говорят, что семантику такого поправлять не будут. Может просто запретят что-то такое делать в будущем (или нет, who knows). Мб потому стоит ещё и отказаться от инициализации с помощью =. Просто на всякий случай.
Хотя есть аргумент за такой стиль. У вас будет одинаковый способ “инициализации” переменных и типов:

auto x = …;
using T = …;


Для типов тогда лучше явно указывайте тип: auto i = int{1} (это всё мысли из AAA от Herb Sutter). В защиту такого подхода приводится поинт, что вы не забудете инициализировать вашу переменную. Хотя и тут есть траблы:

std::string x = “1”;
auto x = “1”s; // C++14


Вот эту s в конце (литерал) очень легко забыть/не обратить на неё внимания.
Ещё можно заметить, что такой способ работает (работал*) только для movable/copyable типов, иначе CE:

auto a = std::atomic<int>{9}; // CE before C++17

Ну и всякие другие проблемы бывают. Например с производительностью некоторых типов.

Чисто из опыта совет: помните, что значит первая буква в AAA — Almost. Потому что иногда поиск типа переменной становится неприятным муторным занятием, попросту тратящим время.

Ещё классический момент это инициализация вектора:

std::vector<int> v(3, 1); // 1 1 1
std::vector<int> v{3, 1}; // 3 1


Ну тут всё понятно. Не будем обсуждать.

В докладе Nicolai Josuttis можно посмотреть про это всё счастье подробнее. Там ещё много маслин словить можно.
  • 👍 11
  • ❤ 1
More from @thisnotes
  1. Sep 24, 2026#cpp Представьте вот такой код: auto object = GetObject(params...); auto another = object;…
  2. Sep 17, 2026#common Сидите вы себе спокойно, разрабатываете поиск каких-нибудь объектов. Может это тов…
  3. Sep 9, 2026#cpp #books Да, книга 2001ого года. Мы ровесники. И да, в ней в основном обсуждаются какие…
  4. Sep 2, 2026#perf Попробовал собрать в кучку (кажется, немного сумбурно всё же) мысли по двум моментам…
  5. Aug 31, 2026Давайте новый тег заведём: #perf Во-первых, надо понять, что я вообще понимаю под перфом,…
  6. Aug 27, 2026#common Мы часто делаем системы, которые обладают какими-то ограничениями. Ограничения наш…
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 →