10

Consider this code.

struct A {
    int i;
};

struct B {
    char c;
};

struct C {
    double d;
};

void f(A a);
void f(B b);
void f(C c);

void g()
{
    f({5});
}

Here I get an ambiguity in f({5});. But it seems that struct A's constructor is an exact match for {5}, while the second one needs an integral promotion, while the last one needs a floating-point conversion.

So why is there an ambiguity?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Karen Melikyan
  • 195
  • 1
  • 9

2 Answers2

8

Even if the first conversion in the sequence is of a worse rank, both conversion sequences end up being user defined conversions, since they both convert to a user defined type.

[over.ics.user]

1 A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-defined conversion ([class.conv]) followed by a second standard conversion sequence.

A user defined conversion anywhere in the implicit conversion sequence gives the entire sequence a "user defined conversion" rank. So the two conversion sequences are in fact of the same rank, and as such neither is better than the other.

The function call is ambiguous on account of that.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Also, I think, direct initialization here is play, although not obviously. Even if we add some extra fields to structures, the call with lesser number of elements in initializer list would result in ambiguity, because an initilizer list can be converted to any of those types. – Swift - Friday Pie Jun 10 '19 at 08:02
  • @Swift-FridayPie - `{5}` is *copy-list-initializtion*. Direct initialization would have looked like `A{5}`, and in that case there would not be any ambiguity. – StoryTeller - Unslander Monica Jun 10 '19 at 08:04
-2

It is because integer can be converted to double as double is a bigger data type. It is known as implicit conversion.

This function call g() can go to f(C c) as well as f(A a).

Evg
  • 25,259
  • 5
  • 41
  • 83