创建 c++ 对象的模板 class 的新实例

Make new instance of the template class of a c++ object

所以如果我有

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

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

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

这可能吗?

不,您可以通过特化模板来创建 class 模板的实例。为此,您可以将要使用的类型放在尖括号中:

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

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

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

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


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

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;

Demo