Question: I fixed a bug recently. 

In the following code, one of the overloaded function was const and the other one was not. The issue will be fixed by making both functions const. 

My question is why compiler only complained about it when the parameter was 0. 

```
#include <iostream>
#include <string>

class CppSyntaxA
{
public:
    void f(int i = 0) const { i++; }
    void f(const std::string&){}
};

int main()
{
    CppSyntaxA a;
    a.f(1);  // OK
    //a.f(0);  //error C2666: 'CppSyntaxA::f': 2 overloads have similar conversions
    return 0;
}

```

Answer: 
`0` is special in C++. A null pointer has the value of `0` so C++ will allow the conversion of `0` to a pointer type. That means when you call

```
a.f(0);

```

You could be calling `void f(int i = 0) const` with an `int` with the value of `0`, or you could call `void f(const std::string&)` with a `char*` initialized to null.

Normally the `int` version would be better since it is an exact match but in this case the `int` version is `const`, so it requires "converting" `a` to a `const CppSyntaxA`, where the `std::string` version does not require such a conversion but does require a conversion to `char*` and then to `std::string`. This is considered enough of a change in both cases to be considered an equal conversion and thus ambiguous. Making both functions `const` or non `const` will fix the issue and the `int` overload will be chosen since it is better.
> 
> My question is why compiler only complained about it when the parameter was 0. 
> 
> 
> 

Because 0 is not only an integer literal, but it is also a null pointer literal. 1 is not a null pointer literal, so there is no ambiguity.

The ambiguity arises from the implicit converting constructor of `std::string` that accepts a pointer to a character as an argument.

Now, the identity conversion from int to int would otherwise be preferred to the conversion from pointer to string, but there is another argument that involves a conversion: The implicit object argument. In one case, the conversion is from `CppSyntaxA&` to `CppSyntaxA&` while in other case it is `CppSyntaxA&` to `const CppSyntaxA&`.

So, one overload is preferred because of one argument, and the other overload is preferred because of another argument and thus there is no unambiguously preferred overload.

> 
> The issue will be fixed by making both functions const. 
> 
> 
> 

If both overloads are `const` qualified, then the implicit object argument conversion sequence is identical, and thus one of the overloads is unambiguously preferred.