ОК, давайте разберем то, что говорит стандарт:
Преобразования типов объектов класса могут быть определены конструкторами и функциями преобразования.
Теперь давайте притворяться, что мы ничего не знаем о значении этих слов. Это предложение говорит о концепции, называемой «преобразованием типов», но оно конкретно говорит о «преобразованиях типов объектов классов». Таким образом, мы говорим не о всех преобразованиях типов, а только о их подмножестве.
Затем говорится «может быть указано» и перечисляются несколько способов их указания. Следующее предложение:
Эти преобразования называются пользовательскими преобразованиями
Обратите внимание, что здесь не говорится "эти конструкторы" или "эти функции преобразования". Там написано "эти обращения". Что ж, единственные "преобразования", о которых говорилось, это подмножество, обсуждавшееся ранее: "преобразования типов объектов класса". И поэтому это предложение можно переформулировать так:
[преобразования типов объектов класса] называются преобразованиями, определенными пользователем.
Итак, что мы можем сказать из этого является то, что объекты класса могут иметь преобразования типов. Эти преобразования могут быть определены определенными вещами в классе. И этот конкретный тип преобразований типов называется «определяемыми пользователем преобразованиями».
Стандарт не говорит, что сам конструктор является либо преобразованием типа, либо преобразованием, определенным пользователем. , Конструкторы - это только один способ указать такое преобразование.
Далее мы переходим к [class.conv.ctor] / 1 :
Конструктор объявленный без спецификатора функции явным образом указывает преобразование типов его параметров (если они есть) в тип его класса. Такой конструктор называется конвертирующим конструктором.
ОК, теперь у нас есть определение «конвертирующего конструктора». Действительно, учитывая это определение, параграф 3 (объявляющий, что не explicit
конструкторы копирования / перемещения являются конвертирующими конструкторами) является избыточным; Приведенное выше определение проясняет, что они есть.
Быть «конвертирующим конструктором» - это свойство конструктора. Процесс пользовательского преобразования прописан, и он, безусловно, может вызвать «конструктор преобразования». Но ни в коем случае не утверждается и не подразумевается, что это процесс only , с помощью которого можно вызвать «конструктор преобразования».
Следовательно, тот факт, что конструктор копирования является «преобразованием» «Конструктор» не следует истолковывать как означающее, что все, что приводит к вызову конструктора копирования, само является преобразованием, определяемым пользователем. Определяемые пользователем преобразования происходят, когда стандарт сообщает , что они происходят.
В описываемом вами примере происходящее определено в [dcl.init] /17.6.2:
В противном случае, если инициализация является прямой инициализацией, или если это инициализация копирования, где версия cv-без квалификации исходного типа того же класса, или производный класс, класс места назначения, конструкторы рассматриваются. Применимые конструкторы перечисляются ([over.match.ctor]), и лучший выбирается через разрешение перегрузки. Выбранный таким образом конструктор вызывается для инициализации объекта, с выражением инициализатора или списком выражений в качестве аргументов. Если конструктор не применяется, или разрешение перегрузки неоднозначно, инициализация неверна.
Нигде в этом правиле Само не указано, что преобразование любого вида напрямую выполнила. Происходит разрешение перегрузки конструкторов с одним аргументом типа назначения. Правила разрешения перегрузки могут учитывать несколько преобразований, поскольку он пытается подогнать данный аргумент к различным возможностям параметров в наборе перегрузки. Но это общие c, связанные с любым разрешением перегрузки любого вызова функции.
То есть тот факт, что выбранная именно так функция считается «конструктором преобразования», не означает, что определяемое пользователем преобразование вызвало ее вызов.