Ответ 1
Это действительно очень странно. Прежде всего, независимо от того, должен ли здесь вызываться конструктор копирования, поскольку [class.base.init]/7 не различает инициализацию базы и инициализацию члена, поведение должно быть одинаковым в обоих случаях. Я не могу найти никаких дополнительных формулировок в стандарте, которые каким-то образом вводили бы асимметрию между инициализацией базы против инициализации члена. Исходя из этого, я бы сказал, что мы можем заключить, что здесь, так или иначе, есть ошибка компилятора. ICC и MSVC, по крайней мере, ведут себя последовательно, когда дело доходит до инициализации базы против инициализации члена. Однако ICC и MSVC не согласны с тем, должен ли код быть принят или нет.
Я полагаю, что ответ на вопрос о том, следует ли вызывать конструктор копирования, можно найти, если мы снова посмотрим на [class.base.init]/7:
Список выражений или braced-init-list в mem-initializer используется для инициализации обозначенного подобъекта (или, в случае делегирующего конструктора, полного объекта класса) в соответствии с правилами инициализации [dcl.init] для прямая инициализация. [...]
Акцент мой. Я считаю, что релевантный бит [dcl.init] должен быть [dcl.init]/17.6, где мы находим:
Если тип назначения является (возможно, cv-квалифицированным) типом класса:
Если выражение инициализатора является prvalue, а версия cv-unqualified типа источника является тем же классом, что и класс назначения, выражение инициализатора используется для инициализации объекта назначения. [...]
В противном случае, если инициализация является прямой инициализацией, или если это инициализация копирования, где cv-неквалифицированная версия исходного типа является тем же классом или производным классом класса назначения, конструкторы рассматриваются. Применимые конструкторы перечислены ([over.match.ctor]), и лучший из них выбирается с помощью разрешения перегрузки ([over.match]). [...]
[...]
Если применить 17.6.2, это будет означать, что должен быть вызван конструктор копирования, что сделает MSVC единственным основным компилятором, который ведет себя правильно в этом примере. Тем не менее, моя интерпретация заключается в том, что 17.6.1 применяется в целом, а icc корректен, т.е. Ваш код должен компилироваться. Это означает, что у вас есть потенциально даже две ошибки в GCC и clang (инициализация базы и инициализация члена ведут себя по-разному + mem-initializer вызывает copy-ctor, хотя это не должно быть), и одна в MSVC…