C ++ implicit casting

Consider this case:

ClassA obA;
ClassB obB;

obA = obB;

      

Is it correct that if it ClassA

has a constructor that has a type parameter ClassB

, it will be called in that case?

If ClassB

there is an overloaded cast operator that converts an object ClassB

to an object ClassA

, the operator method is called. If there is an appropriate constructor and an overloaded casting operator that will be called? Where can I read about this?

+3


source to share


2 answers


Is it correct that if it ClassA

has a constructor that has a type parameter ClassB

, it will be called in that case?

Yes, constructors are considered for implicit type conversions:

The type of conversion of class objects can be specified by constructors and conversion functions. These conversions are called custom conversions and are used for implicit type conversions (Section 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9).

A constructor with a signature ClassA::ClassA(ClassB)

is called a constructor conversion. During a function call such as assignment, constructors and custom conversion operators are compiled into an overload set and the best one is chosen for the conversion.

If the constructor is selected: if the source type is the default type, it creates a class value of the source type ( ClassA

), initialized with the target type ( ClassB

), and this is used to initialize the parameter. If the source type is a link, the link initialization rules are used .


Assignment operators are implicitly generated in ClassA

(unless they have been overridden). It:

ClassA& operator=(ClassA const&);
ClassA& operator=(ClassA      &&);

      



The implicit conversion sequence can choose either a constructor or a conversion function to convert from ClassB -> ClassA const&

or ClassB -> ClassA&&

.

However, in this case, following your scenario, the conversion will fail as it will 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 viable transformation functions to be used for the conversion. So the conversion is ambiguous and we are presented with a compilation error.

Custom conversions are applied only where they are unambiguous (10.2, 12.3.2).

If we change the signature of the converting constructor in the class A

to A::A(B const&)

, then the conversion operator in B

will be used because the constructor A

requires a qualifying conversion (append const

).

In cppreference , where you can learn more.

+3


source


This code:

ClassA obA;
ClassB obB;

obA = obB;

      

not what you think it is (*) . This code:

ClassB obB;
ClassA  obA = obB;

      

will work (as provided) if:

1.has ClassA

a constructor that takes ClassB

as a parameter:

class ClassA
{
public:
    ClassA(const ClassB& b)
    {
        //construct *this from b
    }
};

      

2. ClassB

defined conversion operator type:



class ClassB
{
public:
    operator ClassA() const
    {
        //construct ClassA from *this
    }
};

      

If class ClassA has an overloaded cast operator that has a parameter of type ClassB [...].

You meant a constructor , not a casting operator , right? You are trying to convert ClassA

to ClassB

, so the converting operators from ClassA

in this case are irrelevant.


(*) You assign obB

in obA

after obA

drawing, so only the second point is applicable in your case. You can also make it work by adding an assignment operator:

3.

class ClassA
{
public:
    ClassA& operator=(const ClassB& b)
    {
        //assign b to *this
    }
};

      

which will be called in your case.

+3


source







All Articles