Are variadic constructors supposed to hide the implicitly generated ones, i.e. the default constructor and the copy constructor?
struct Foo
{
template<typename... Args> Foo(Args&&... x)
{
std::cout << "inside the variadic constructor\n";
}
};
int main()
{
Foo a;
Foo b(a);
}
Somehow I was expecting this to print nothing after reading this answer, but it prints inside the variadic constructor twice on g++ 4.5.0 🙁 Is this behavior correct?
It also happens without variadic templates:
struct Foo
{
Foo()
{
std::cout << "inside the nullary constructor\n";
}
template<typename A> Foo(A&& x)
{
std::cout << "inside the unary constructor\n";
}
};
int main()
{
Foo a;
Foo b(a);
}
Again, both lines are printed.
Declaration of the implicitly declared copy constructor is not, in fact, being suppressed. It’s just not being called due to the rules of overload resolution.
The implicitly declared copy constructor has the form
Foo(const Foo&). The important part of this is that it takes a const reference. Your constructor template takes a non-const reference.ais not const, so the non-const user-declared constructor template is preferred over the implicitly-declared copy constructor. To call the implicitly-declared copy constructor, you can makeaconst:or you can use
static_castto obtain a const reference toa:The overload resolution rules that describe this are found mostly in §13.3.3.2/3 of the C++0x FCD. This particular scenario, with a combination of lvalue and rvalue references, is sort of described by the various examples on page 303.
A variadic constructor template will suppress the implicitly declared default constructor because a variadic constructor template is user-declared and the implicitly declared default constructor is only provided if there are no user-declared constructors (C++0x FCD §12.1/5):
A variadic constructor template will not suppress the implicitly declared copy constructor because only a non-template constructor can be a copy constructor (C++0x FCD §12.8/2, 3, and 8):