我正在尝试这样做:
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在上面的代码中,我想将Universal的构造函数中的所有参数都转发给T的构造函数。
我怎么能做到呢?
发布于 2016-10-11 20:57:52
你需要让Universal构造器成为一个可变模板,并使用一个参数包和完美的转发。
template<typename T>
struct Universal {
T _t;
template <typename... Args>
Universal(Args&&... args) : _t(std::forward<Args>(args)...) {}
};不幸的是,正如AndyG在评论中指出的那样,这意味着如果您尝试复制非常量Universal对象,则首选转发版本-因此您需要显式的常量和非常量复制构造函数!
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.
};或者使用this answer中所示的SFINAE方法,以确保首选默认构造函数。
发布于 2016-10-11 20:54:20
简单:
template<typename T>
struct Universal {
T _t;
Universal(const T& val) : _t(val) {}
};如果您关心的是性能,或者如果您想支持仅移动类型,您可以转发参数:
template<typename T>
struct Universal {
T _t;
template <class U>
Universal(U&& val) : _t(std::forward<U>(val)) {}
};请注意,我们需要ctor的模板参数U才能进行转发。T&&将只是一个右值引用。
如果你想得到更多花哨的东西,你可以就地构造:
template<typename T>
struct Universal {
T _t;
template <class... Args>
Universal(Args&&... args) : _t(std::forward<Args>(args)...) {}
};正如AndyG在评论中建议的那样,如果您希望cpy和mv ctors按预期工作,则需要完成额外的工作。
规则是:保持简单,除非有充分的理由证明复杂性是合理的。我认为第一个变种对你来说已经足够了。
https://stackoverflow.com/questions/39977551
复制相似问题