Помимо проблем с производительностью, есть еще одна очень важная, которую я бы назвал ремонтопригодностью и расширяемостью кода.
Если T является POD, и вы начинаете предпочитать список инициализации, то, если один раз T изменится на тип не POD, вам не нужно будет что-либо менять при инициализации, чтобы избежать ненужных вызовов конструктора, потому что он уже оптимизирован.
Если тип T имеет конструктор по умолчанию и один или несколько пользовательских конструкторов и один раз вы решили удалить или скрыть конструктор по умолчанию, то, если использовался список инициализации, вам не нужно обновлять код, если ваш пользователь определенные конструкторы, потому что они уже правильно реализованы.
То же самое с константными членами или ссылочными элементами, скажем, изначально T определяется следующим образом:
struct T
{
T() { a = 5; }
private:
int a;
};
Далее вы решаете квалифицировать a как const, если вы будете использовать список инициализации с самого начала, тогда это было изменение одной строкой, но, имея T, как указано выше, также необходимо выкопать определение конструктора, чтобы удалить назначение :
struct T
{
T() : a(5) {} // 2. that requires changes here too
private:
const int a; // 1. one line change
};
Не секрет, что обслуживание гораздо проще и менее подвержено ошибкам, если код был написан не «обезьяной кода», а инженером, который принимает решения, основываясь на более глубоком рассмотрении того, что он делает.