Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

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

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
";
    }

    template<typename... Args>
    Foo(Args&&... args)
    {
        std::cout << "variadic constructor
";
    }

    std::string message;
};

int main()
{
    Foo f1;
    Foo f2(f1); // this calls the variadic constructor, but I want the copy constructor.
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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
";
    }

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

};

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&.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...