Compiler offers private constructor as a candidate in program code

c++, clang, constructor, gcc

Solution

It's ambiguous for an explicit reason, as according to the standard:

[class.access/5]

It should be noted that it is access to members and base classes that is controlled, not their visibility. Names of members are still visible, and implicit conversions to base classes are still considered, when those members and base classes are inaccessible. The interpretation of a given construct is established without regard to access control. If the interpretation established makes use of inaccessible member names or base classes, the construct is ill-formed.

And that visibility means that the compiler must consider both overloads for the construction, and they are equally good for the argument you passed.

Since the constructor is private, and therefore only accessible withing the scope of the class and its members, just remove the default parameter value. You can maintain this default value in your classes definition in other ways. For instance, by introducing a constant in the classes implementation file:

int const default_b = 0;

// ...

return Test{a, default_b};

Problem

``` #include <iostream> using namespace std; class Test{ private: Test(int a, int b=0) { cout << "private constructor\n"; } public: Test(int a) { cout << "public constructor\n"; } }; int main() { Test t(1); } ``` When I attempted to compile the code `gcc` says: ``` test.cpp: In function ‘int main()’: test.cpp:20:10: error: call of overloaded ‘Test(int)’ is ambiguous Test t(1); ^ test.cpp:12:2: note: candidate: Test::Test(int) Test(int a) ^ test.cpp:7:2: note: candidate: Test::Test(int, int) Test(int a, int b=0) ^ test.cpp:5:7: note: candidate: Test::Test(const Test&) class Test{ ^ ``` and `clang` says: ``` test.cpp:20:7: error: call to constructor of 'Test' is ambiguous Test t(1); ^ ~ test.cpp:7:2: note: candidate constructor Test(int a, int b=0) ^ test.cpp:12:2: note: candidate constructor Test(int a) ^ test.cpp:5:7: note: candidate is the implicit copy constructor class Test{ ^ 1 error generated. ``` What is the reason of the ambiguity? Since `Test(int,int)` is private, it shouldn't be possible to call it in `Test t(1)`. A possible answer is (what I thought initially), it makes two identical signatures of constructors possible, i.e `Test()` can be called with only one `int` in private constructor. But in the program code `Test t(1)` is only feasible for public constructors, so it shouldn't offer the private constructor as a candidate. Why does it say that?

Original source

Related problems