How do I get the copy constructor called over a variadic constructor?

c++, c++11, templates, variadic-templates

Solution

This actually has nothing to do with the fact that the constructor is variadic. The following class with a non-variadic constructor template exhibits the same behavior:

struct Foo
{
    Foo() { }

    Foo(const Foo& x)
    {
        std::cout << "copy constructor\n";
    }

    template <typename T>
    Foo(T&& x)
    {
        std::cout << "template constructor\n";
    }

};

The problem is that the constructor template is a better match. To call the copy constructor, a qualification conversion is required to bind the non-const lvalue `f1` to `const Foo&` (the const qualification must be added).

To call the constructor template, no conversions are required: `T` can be deduced to `Foo&`, which after reference collapsing (`Foo& &&` -> `Foo&`), gives the parameter `x` type `Foo&`.

You can work around this by providing a second copy constructor that has a non-const lvalue reference parameter `Foo&`.

Problem

In the following code, the variadic constructor is called twice. How can I get the copy constructor to be called instead of the single argument version of the variadic constructor when appropriate? ``` #include <iostream> struct Foo { Foo(const Foo &) { std::cout << "copy constructor\n"; } template<typename... Args> Foo(Args&&... args) { std::cout << "variadic constructor\n"; } std::string message; }; int main() { Foo f1; Foo f2(f1); // this calls the variadic constructor, but I want the copy constructor. } ```

Original source