创建一个c++对象的模板类的新实例



所以如果我有

template <class T>
class Object {
// stuff
};

我在一个函数中收到了一个对象的实例,我想调用类T的构造函数。

void foo(Object object) {
auto newT = object::T();
}

这可能吗?

通常,最好的解决方案是模板化内部类型:

template <class T>
void foo(Object<T> object) {
T newT;
}

然而,有时(使用更多的元编程)这种解决方案会比替代方案更详细:


选项1:将模板变量存储在Object类中:

template <class T>
class Object {
// stuff
public:
using inner_type = T;
};

然后你可以访问这样的模板类型:

template <class Obj>
void foo(Obj object) {
typename Obj::inner_type newT;
}

选项2:生成类型特征(无需将inner_type添加到Object):

template <class T>
struct tag {
using type = T;
};
template <class>
struct inner;
template <template <class> class S, class T>
struct inner <S<T>> : tag<T> {};
template <typename T>
using inner_t = typename inner<T>::type;

然后你可以这样使用:

template <class Obj>
void foo(Obj object) {
inner_t<Obj> newT;
}

最好将inner_type推广为采用第一个内部参数,这样它就可以处理具有更多参数的模板类型,如std::vector(第二个参数有默认值):

template <class>
struct front;
template <template <class, class...> class R, class S, class ... Ts>
struct front <R<S, Ts...>> : tag<S> {};
template <typename T>
using front_t = typename front<T>::type;

演示

否,您可以通过专门化模板来创建类模板的实例。你可以把你想使用的类型放在尖括号里:

void foo(Object<int> object) {
//  auto newobj = Object<int>(); this will work
Object<int> newobj;               // but this has less cruft
}

template <class U>
void foo(Object<U> object) {
//  auto newobj = Object<U>();
Object<U> newobj  {object};
}

请记住,符号T不存在于模板定义之外。为了得到一个";真实的";Object必须输入一个实际类型。我选择了int,但您可能会使用其他内容。

当然,只有当stuff包含相应的构造函数时,这才会起作用

template <class T>
class Object {
// stuff
public:
Object(); // often implicit but sometimes not
Object(Object<T> const &i) = default;
// more stuff
};

最新更新