创建 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;
所以如果我有
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;