#include <iostream>
using namespace std;
struct Y;
struct X
{
X(const Y&) { cout << "converting constructor" << endl; }
};
struct Y
{
operator X() { cout << "conversion function" << endl; }
};
void f(X x) {}
int main()
{
Y y;
f(y);
}
In the above the conversion function is given priority to the converting constructor by my compiler (gcc 4.6.1), however in the standard it states that:
User-defined conversions are applied only where they are unambiguous
It would seem that there is ambiguity in this case. Can anyone explain the contradiction?
I would have expected the above to not compile. I'm also pretty sure years ago that Scott Meyers wrote about this specific example and said that it wouldn't compile. What am I missing?
Because X constructor wants a const
argument, it prefers the operator. If you remove the const
in the X constructor then compiler complains about ambiguity. If there are more than one functions with reference parameters, the one with the most relaxed const qualification is preferred.
A good answer here
There is no ambiguity here, the only valid conversion is provided by the conversion function.
Note that y
is not a const
, your conversion constructor needs a const
argument.
There would be a ambiguity, If your conversion constructor took a non const reference.
Online Sample:
#include <iostream>
using namespace std;
struct Y;
struct X
{
X(Y&) { cout << "converting constructor" << endl; }
};
struct Y
{
operator X() { cout << "conversion function" << endl; }
};
void f(X x) {}
int main()
{
Y y;
f(y);
return 0;
}
Output:
prog.cpp: In member function ‘Y::operator X()’:
prog.cpp:13: warning: no return statement in function returning non-void
prog.cpp: In function ‘int main()’:
prog.cpp:21: error: conversion from ‘Y’ to ‘X’ is ambiguous
prog.cpp:13: note: candidates are: Y::operator X()
prog.cpp:8: note: X::X(Y&)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With