Reputation: 153
What does standard say about the precedence of Converting Constructor and Conversion Operator, in simple language?
Also, I can see that when I have 2 classes myClass
and otherClass
and I want to convert otherClass
to myClass
as shown below, then Conversion operator gets called for class otherClass
myClass mc = otherclass();//creates temp for otherClass
This behavior is same in gcc as well as MSVC.
But this behavior is different across above compilers when I do something like below-
otherClass oC;
myClass mc = oC;//for gcc (C++11): Ambiguous, for MSVC: calls myClass Conversion Constructor
So, my question is why initializing from temporary in 1st case is different than the 2nd case? And secondly why compilers differ behavior for 2nd case?
EDIT: Classes defined as
#include <iostream>
using namespace std;
class otherClass;
class myClass {
public:
myClass(){}
myClass(otherClass&) {
cout << "called myClass's conversion constructor" << endl;
}
};
class otherClass {
public:
operator myClass () {
cout << "called otherClass's conversion operator" << endl;
return myClass ();
}
};
int main()
{
otherClass oc;
myClass mc = oc;
myClass mc1 = otherClass();
return 0;
}
Upvotes: 1
Views: 86
Reputation: 238311
Which gets precedence when Converting Constructor as well as Conversion Operator are defined
Neither.
why compilers differ this conversion?
If the conversion sequence is ambiguous, then the program is ill formed. Thus the compiler is allowed to not produce a program, and required to diagnose the issue. Allowing such ambiguous conversion intentionally would be considered a language extension, but failing to diagnose regardless of the extension would be a failure to conform to the standard.
If the conversion sequence is unambiguous, and there is no other reason for the program to be ill formed, then a compiler that refuses to compile it does not conform to the standard.
Edit: Regarding the added example: The conversion of myClass mc = oc
is indeed ambiguous and the program is ill-formed. So, a possible reason for difference in behaviour is either a language extension of the compiler that allows it, or a compiler bug. If it is not diagnosed, then the compiler does not conform to the standard. I recommend disabling language extensions.
myClass mc1 = otherClass()
is well-formed because there is only one valid candidate for the conversion. The converting constructor is not a valid candidate because lvalue references to non-const cannot be bound to rvalues.
Upvotes: 3