Reputation: 2858
I have the class
class A
{
public:
class Key
{
Key() {}
Key(Key const &) {}
};
A(Key key, int a = 5) {}
};
The constructor for Key
is private, so no one should be able to construct an object A
. However, with the following code:
int main() {
A a(A::Key()); // this compiles !!!
A a2(A::Key(), 5); // this doesn't
// somehow defaulting the argument causes the private constructor
// to be OK - no idea why
return 0;
}
By making use of the default argument for int a
in my constructor, the compiler happily compiles my usage of A::Key()
despite the fact that it is private. If I explicitly give a value for a
, though, the compiler correctly recognizes that I am trying to use a private constructor and errors out. Why is this? Is there someway to force the compiler to error out for the first example as well?
See here for live example.
Upvotes: 6
Views: 124
Reputation: 180500
This is because of the most vexing parse.
A a(A::Key());
Does not create a A
named a
and construct it with a temporary A::Key
. It creates a function a
that returns an A
and takes an unnamed pointer to function that returns a A::Key
.
If you add a pair of parentheses to it you will get a compiler error
A a((A::Key()));
That you are trying to call a private constructor. Alternatively you can use uniformed initialization which also disambiguate it and will cause a compile error
A a(A::Key{});
Upvotes: 7