Правильно ли, что если ClassA
имеет конструктор, который имеет параметр типа ClassB
, он будет называться в этом случае?
Да, конструкторы считаются для неявного типа:
Тип преобразования объектов класса могут быть определены с помощью конструкторов и функции преобразования. Эти преобразования называются пользовательскими преобразованиями и используются для неявных преобразований типов (раздел 4), для инициализации (8.5) и для явных преобразований типов (5.4, 5.2.9).
Конструктор с подписью ClassA::ClassA(ClassB)
называется превращающего конструктор. Во время вызова функции, такого как назначение, конструкторы и пользовательские операторы преобразования скомпилируются в набор перегрузки и выбирается лучший для преобразования.
Если выбран конструктор: Если тип источника является типом по значению, он создает prvalue типа типа источника (ClassA
) инициализирован с типом типа назначения (ClassB
), и это используется для инициализации параметра. Если тип источника является ссылкой, используются reference-initialization rules.
Операторы присваивания неявно сгенерированные в ClassA
(при условии, что они не были переопределены). Они: последовательность
ClassA& operator=(ClassA const&);
ClassA& operator=(ClassA &&);
неявного преобразования может выбрать либо конструктора или преобразование функции для преобразования из ClassB -> ClassA const&
или ClassB -> ClassA&&
.
Однако в этом случае переход по вашему сценарию не сможет добиться успеха, поскольку это будет неоднозначно. Рассмотрим:
struct B { operator struct A(); };
struct A {
A() = default;
A(B) {}
};
B::operator A() { return A(); }
int main()
{
A a; B b;
a = b; // Error! Ambiguous conversion
}
Оба A::A(B)
и B::operator A()
являются жизнеспособные функции преобразования, чтобы использовать для преобразования. Таким образом, преобразование неоднозначно, и нам дается компиляционная ошибка.
Пользовательские преобразования применяются только там, где они недвусмысленны (10.2, 12.3.2).
Если изменить подпись конвертерной-конструктор в классе A
к A::A(B const&)
, то оператор преобразования в B
будет использоваться, поскольку конструктор по A
«s требует квалификации-преобразование (добавление const
).
Существует нить на cppreference, где вы можете узнать больше.
Взгляните на этот вопрос, это может помочь вам: http://stackoverflow.com/questions/1092714/conversion-precedence-in-c –
Это не кастинг, это преобразование. – molbdnilo
Как только мы преодолеем путаницу оператора OP с вызовом конструктора, это, похоже, ответит на вопрос: http://stackoverflow.com/questions/1384007/conversion-constructor-vs-conversion-operator-precedence –