Is it right, that if ClassA
has a constructor which has a parameter of type ClassB
, it will be called in this case?
Yes, constructors are considered for implicit type conversions:
Type conversions of class objects can be specified by constructors and by conversion functions. These
conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for
initialization (8.5), and for explicit type conversions (5.4, 5.2.9).
A constructor with the signature ClassA::ClassA(ClassB)
is called a converting-constructor. During a function call such as the assignment, constructors and user-defined conversion operators are compiled into an overload set and the best one is chosen for the conversion.
If a constructor is chosen: If the source type is a by-value type, it creates a prvalue of the type of the source type (ClassA
) initialized with the type of the destination type (ClassB
), and that is used to initialize the parameter. If the source type is a reference, reference-initialization rules are used.
The assignment operators are implicitly-generated in ClassA
(assuming they haven't been overriden). They are:
ClassA& operator=(ClassA const&);
ClassA& operator=(ClassA &&);
An implicit-conversion sequence can choose either a constructor or conversion function to convert from ClassB -> ClassA const&
or ClassB -> ClassA&&
.
However, in this case, going by your scenario, the conversion would not be able to succeed as it would be ambiguous. Consider:
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
}
Both A::A(B)
and B::operator A()
are both viable conversion functions to use for the conversion. As such, the conversion is ambiguous and we are given a compile error.
User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2).
If we change the signature of the converting-constructor in class A
to A::A(B const&)
, then the conversion operator in B
will be used because the A
's constructor requires a qualification-conversion (addition of const
).
There is a thread on cppreference where you can learn more.