X x1(1);
X x2 = X(1);
X x3 = (X)1;
Причина в том, что все они не совсем эквивалентны.
Первый - прямая инициализация , а второй и третий - копирование-инициализация .Для инициализации копирования, конструктор копирования должен быть общедоступным, иначе компилятор выдаст ошибку.
Теперь возникает вопрос: если 2-й и 3-й требует, чтобы copy-ctor был общедоступным, то почему следующий вывод:
X(int i)
X(int i)
X(int i)
Это, безусловно, говорит о том, что copy-ctor никогда не вызывается, что является правдой.Компилятор просто исключил вызов copy-ctor.Согласно §8.5 / 14, в таких случаях компилятору разрешается исключать необходимость вызывать copy-constructor.Вот почему вы не видите, что вызывается copy-ctor.
Немного изнутри: во 2-м и 3-м случае сначала создается временный объект, вызывая X(int i)
, затем этот временный объект должен был быть переданкопировать-ctor для копирования-инициализации объявляемого объекта.Но компилятор оптимизирует этот шаг, исключая вызов copy-ctor.