Sarvesh
Sarvesh

Reputation: 153

Which gets precedence when Converting Constructor as well as Conversion Operator are defined and why compilers differ this conversion?

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

Answers (1)

eerorika
eerorika

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

Related Questions