2

I was learning about the explicit keyword for conversion constructors and cast operators, and I had to ask: What happens when an implicit conversion between user-defined types has both a conversion constructor AND a cast operator written for it? It seems like conversion rules are really complicated. I tried the following code:

class Type2;

class Type1 {
public:
Type1 (int num) {
  number1 = num;
}
Type1 (Type2&);
  int number1;
};

class Type2 {
public:
Type2 (int num) {
  number2 = num;
}
Type2 (Type1&);
operator Type1() const;
  int number2;
};

Type1::Type1 (Type2& arg) {
  number1 = arg.number2;
}

Type2::Type2 (Type1& arg) {
  number2 = arg.number1;
}

Type2::operator Type1() const {
  Type1 cast = Type1(500);
  return cast;
}

void testFunction(Type1 contention){
  cout << contention.number1 << endl;
}

int main()
{
  Type2 toBeConverted = Type2(5);
  testFunction(toBeConverted);
}

In MVSE 2012, Microsoft's compiler gave me an error indicating an ambiguity that couldn't be processed: error C2664: 'testFunction' : cannot convert parameter 1 from 'Type2' to 'Type1' But GCC compiled the code just fine, preferring the constructor (which causes 5 to be printed) over the operator (which causes 500 to be printed).

I found an article here: Conversion constructor vs. conversion operator: precedence It says, among other things: "So, another rule says that when you have two viable functions whose parameters are references, then the candidate having the fewest const qualification will win. That's why your conversion function wins. Try making operator B a const member function. You will notice an ambiguity." It also said that without turning on -pedantic in GCC, the constructor will seem to have priority over the operator regardless and the ambiguity won't be recognized. In GCC it gave an error indicating ambiguity with -pedantic on (a) when I made the constructor argument a value instead of a reference, and (b) when I kept it a reference and made it const. MVSE 2012 indicated ambiguity as a separate message (Intellisense) in the same way, but whether it did or not, the C2664 "cannot convert" error remained and it would not compile until I commented out one function or the other.

What's the deal? Do I have a compiler that refuses to make these judgements by the standard? Is there an option somewhere to make it work? Is there something else I'm not seeing?

Community
  • 1
  • 1
Lunarian
  • 185
  • 1
  • 6

0 Answers0