Ambiguous call to overloaded function (constructor)

I don't understand where the ambiguity is.

Example.cpp:
1
2
3
4
5
6
7
8
9
10
11
struct A
{
	A();
	A(char);
};

A::A(char c = 'A') {}

int main() {
	A a;
}

Error message from Visual Studio:
example.cpp
example.cpp(10) : error C2668: 'A::A' : ambiguous call to overloaded function
        example.cpp(4): could be 'A::A(char)'
        example.cpp(3): or       'A::A(void)'
        while trying to match the argument list '(void)'
Last edited on
Perhaps clang's error messages are more self-explanatory

test.cc:7:11: warning: addition of default argument on redeclaration makes this
      constructor a default constructor [-Wdefault-arg-special-member]
A::A(char c = 'A') {}
          ^   ~~~
test.cc:4:2: note: previous declaration was not a special member function
        A(char);
        ^
test.cc:10:4: error: call to constructor of 'A' is ambiguous
        A a;
          ^
test.cc:3:2: note: candidate constructor
        A();
        ^
test.cc:7:4: note: candidate constructor
A::A(char c = 'A') {}
   ^
1
2
3
4
void foo() ; // overload 1
void foo( int = 23 ) ; // overload 2

foo() ; // should this call to foo() (overload 1) or should it be foo(23) (overload 2)?  

The C++ compiler does not make a wild guess about the what the programmer intented; it throws the problem back at the person who wrote the code - what precisely do you mean by that? The call, as it is written, is ambiguous - there are two possible, equally good, interpretations.
@JLBorges: Right, but the class declares 2 unambiguous constructors. Then I was attempting to define both of them with one single function (with a default parameter.) Is there some specification saying I can't do that? I don't understand how else this could be interpreted (reasonably.)

1) A a; must call a default constructor.
2) class A { A(); } one has been defined.
Now look for it's declaration. (Should have been linked,)
or does something else magical happen at compile time?

@Cubbi: Thanks, I see how it sees both as default constructors, but why? I didn't know the compiler looks for class member declarations outside of the class body, only the definition (to be linked at compile time.)
A a; could be either. As @JLBorges mentioned since you are using default arguments in your second ctor it cannot distinguish between those two.

So A a; could call A() as you intended
or
A(char); since in that case c would be 'A'.

If you want to solve the ambiguity delete the default argument. So define your ctor as

A::A(char c) {}
1
2
3
4
5
6
7
8
9
10
struct A
{
	A(char);
};

A::A(char c = 'A') {}

int main() {
	A a;
}

So this seems to compile... I always though a default parameter was the same as overloading, but apparently it's not. Thanks eypros!
Topic archived. No new replies allowed.