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