Какой синтаксис инициализации переменных используется в продакшене для новых проектов и почему?

Рейтинг: 1Ответов: 1Опубликовано: 11.04.2023

Собственно, вопрос в заголовке.

Ответы

▲ 3

Есть два лагеря, примерно вот такие:

  1. int i = 42; // Реже `int i(42);`.
    MyClass c(params);
    std::vector<int> vec = {1,2,3};
    
  2. int i{42};
    MyClass c{params};
    std::vector<int> vec{1,2,3};
    

Первый - традиционный способ.

Второй когда-то считался многообещающим и новомодным (во времена C++11) - он запрещает неявные преобразования, и казалось бы запись одинаковая во всех случаях!

Но обнаружилось, что некоторые виды классов ведут себя с ним очень странно. Например, стандартные контейнеры - std::vector<int> v{3} - это вектор из одного числа 3, а std::vector<std::string> v{3} - три пустые строки. Можно было бы переписать контейнеры, чтобы так не происходило, но сейчас этого никто делать не будет.

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

Поэтому я бы по умолчанию придерживался (1). Если интересно, можете почитать доводы сторонников (2), возможно вас переманят на темную сторону силы.


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


Есть еще всякие маргинальные веяния, например

auto x = 42;
auto c = MyClass(params);
auto vec = std::vector<int>{1,2,3};

Или вообще

auto x = int{42};
auto c = MyClass{params};
auto vec = std::vector<int>{1,2,3};