如何获得通过可变参数构造函数调用的复制构造函数?

时间:2012-06-14 16:42:41

标签: c++ templates c++11 variadic-templates

在下面的代码中,可变参数构造函数被调用两次。在适当的时候,如何才能调用复制构造函数而不是变量构造函数的单个参数版本?

#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.
}

2 个答案:

答案 0 :(得分:12)

这实际上与构造函数是可变参数的事实无关。具有非可变构造函数模板的以下类表现出相同的行为:

struct Foo
{
    Foo() { }

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

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

};

问题是构造函数模板更匹配。要调用复制构造函数,需要进行限定转换以将非常量值f1绑定到const Foo&(必须添加const限定条件)。

要调用构造函数模板,不需要转换:T可以推导到Foo&,在引用折叠后(Foo& && - &gt; Foo&),参数x类型Foo&

您可以通过提供具有非常量左值引用参数Foo&的第二个副本构造函数来解决此问题。

答案 1 :(得分:6)

除了传统的复制构造函数之外,只提供一个完全匹配的重载,即一个非const Foo&的重载。然后,您可以通过显式转换委派来电:

Foo(Foo& other) : Foo{const_cast<Foo const&>(other)} { }