Reputation: 655
class A {
public:
int num;
A ( int param ) : num( param ) {}
operator decltype( auto )( ){ return num; }
};
class B {
public:
int num;
A objA;
B ( int param ) : num( param ), objA( param ) {}
//operator A( ) { return objA; } // Works // #1
//operator int( ) { return objA; } // Works // #2
//operator char( ) { return objA; } // Actually Not Needed // #3
//operator double( ) { return objA; } // Actually Not Needed // #4
operator decltype( auto )( ){ return objA; } // Does NOT Work // #5
};
int main(){
A objA( 1 );
int x1 = int( objA );
char y1 = (char) objA;
double z1 = objA;
B objB( 2 );
A objA2 = objB;
int x2 = objB;
char y2 = objB;
double z2 = objB;
return 0;
}
This code does not compile neither with clang nor with gcc, so I assume it is not correct. However, if I comment line #5 and uncomment lines #1 and #2 the program works correctly in both compilers (lines #3 and #4 are not really required).
As far as I know, the necessary conversion sequences are defined in both scenarios. Does anyone know why this program is not correct? What am I missing?
Upvotes: 9
Views: 594
Reputation: 41100
decltype(auto)
will get the exact type (including references and pointers) of the type you're returning. For class A
your conversion operator will return an int
, and for class B
you will get it to return a class A
. I think your belief is that operator decltype(auto) (){/*...*/}
will try to return the class for which the conversion is needed, when in fact you would need a template to do so:
class A {
public:
int num;
A ( int param ) : num( param ) {}
template<class T>
operator T(){ return static_cast<T>(num); }
};
class B {
public:
int num;
A objA;
B ( int param ) : num( param ), objA( param ) {}
template<class T>
operator T ( ){ return static_cast<T>(objA); }
};
Upvotes: 5
Reputation: 172924
Note that implicit conversion sequence could contain only one user-defined conversion. Then the code won't work for int x2 = objB;
; B
converts to A
and A
converts to int
are both user-defined conversion.
If you provide the operator int()
in B
, it works fine because B
could be converted to int
directly. (And also works with char
and double
, to which int
could be converted to by standard conversion.)
Upvotes: 3