如何转发构造函数中所有未知参数来初始化成员对象?

bla*_*all 1 c++ parameter-passing

我正在尝试做这样的事情:

struct Foo {
    int _val;
    Foo(int v) : _val(v){} 
};

struct Bar {
    const std::string &_name;
    Bar(const std::string &name) : _name(name) {} 
};

template<typename T>
struct Universal {
    T _t;
    Universal(...) : _t(...) {} 
};

// I want to use Universal for Foo abd Bar in the same way:
Universal<Foo> UF(9);       // 9 is for Foo
Universal<Bar> UB("hello"); // "hello" is for bar
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我想将Universal的构造函数中的所有参数转发给T的构造函数。

我怎样才能做到呢?

Mar*_*ica 5

您需要使Universal构造函数成为可变参数模板,并使用参数包和完美转发。

template<typename T>
struct Universal {
    T _t;

    template <typename... Args>
    Universal(Args&&... args) : _t(std::forward<Args>(args)...) {} 
};
Run Code Online (Sandbox Code Playgroud)

不幸的是,正如 AndyG 在评论中指出的那样,这意味着如果您尝试复制非常量Universal对象,则转发版本将成为首选 - 因此您需要显式 const 和非常量复制构造函数!

template<typename T>
struct Universal {
    T _t;

    template <typename... Args>
    Universal(Args&&... args) : _t(std::forward<Args>(args)...) {} 

    Universal(const Universal& rhs): _t(rhs._t) {}
    Universal(      Universal& rhs): _r(rhs._t) {}

    // ... but not move constructors.
};
Run Code Online (Sandbox Code Playgroud)

或使用此答案中显示的 SFINAE 方法,以确保首选默认构造函数。