Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: Ambiguity between Converting Constructor and Conversion Function in Initialization of Pass-By-Value Parameter?

#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?

like image 480
Andrew Tomazos Avatar asked Mar 12 '12 02:03

Andrew Tomazos


2 Answers

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

like image 198
perreal Avatar answered Oct 26 '22 16:10

perreal


There is no ambiguity here, the only valid conversion is provided by the conversion function.
Note that yis 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&)

like image 21
Alok Save Avatar answered Oct 26 '22 15:10

Alok Save