dimanche 25 janvier 2015

Direct object initialization vs Intialization with convertion functions

The following program prints 42:



#include <iostream>

struct A
{
operator int(){ return 42; }
};

struct B
{
operator A(){ return A(); }
};

B b;
int a = A(b);
int main(){ std::cout << a << std::endl; } //42


DEMO


But if we try to define cope/move or both contructors it won't work.



#include <iostream>

struct A
{
A(A&&){ std::cout << "A(A&&)" << std::endl; }
A(A&){ std::cout << "A(A&)" << std::endl; }
operator int(){ return 42; }
};

struct B
{
operator A(){ return A(); }
};

B b;
int a = A(b);

int main(){ std::cout << a << std::endl; } //Error


DEMO


I thought, the relevant section, describing that behavior is N4296::8.5/17.7 [dcl.init]



If the destination type is a (possibly cv-qualified) class type:


[...]


— Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered. The applicable conversion functions are enumerated (13.3.1.5), and the best one is chosen through overload resolution (13.3). The user-defined conversion so selected is called to convert the initializer expression into the object being initialized. If the conversion cannot be done or is ambiguous, the initialization is ill-formed.



It shouldn't depends on absence/presence of the constructors. We just should have to have appropriate conversion functions so as to choose the conversion sequence.


Aucun commentaire:

Enregistrer un commentaire