在奇怪的重复模板模式中,我需要将嵌套类型T
更改为TDerivedClass<T>
类型。是否可以通过未完全指定的Base
类来指定Derived1
?诸如此类:class Derived1 : public Base<T, Derived1<"NOT SPECIFIED TYPE SYNTAX">>
,然后完全指定Derived1
,但在Base
内部则充当TDerivedClass<int>
。还是有其他方法可以更改此特定部分的T
?
template<typename T, typename TDerivedClass>
class Base
{
public:
void f()
{
std::vector<T> a;
TDerivedClass b;
TDerivedClass<int> c; // <- want to change T to arbitrary type (to int for example) without changing T
}
};
template<typename T>
class Derived1 : public Base<T, Derived1<T>>
{
};
template<typename T>
class Derived2 : public Base<T, Derived2<T>>
{
};
答案 0 :(得分:3)
您可能需要模板模板参数:
template <typename T, template <typename> class TDerivedClass>
class Base
{
public:
void f()
{
std::vector<T> a;
TDerivedClass<T> b;
TDerivedClass<int> c;
}
};
template<typename T>
class Derived1 : public Base<T, Derived1>
{
};
template<typename T>
class Derived2 : public Base<T, Derived2>
{
};
答案 1 :(得分:2)
您可以专门传递模板类:
template<typename T, template<typename> class TDerivedTemplate>
class Base
{
using TDerivedClass = TDerivedTemplate<T>;
public:
void f()
{
std::vector<T> a;
TDerivedClass b;
TDerivedTemplate<int> c;
}
};
template<typename T>
class Derived1 : public Base<T, Derived1> // Pass the template (Derived1) to instantiate new classes from
{
};
// Since you're changing the pattern anyways, you might as well
// have it detect the template from the type
template<typename TDerivedClass>
class Base;
template<template<typename> class TDerivedTemplate, typename T>
class Base<TDerivedTemplate<T>> {
using TDerivedClass = TDerivedTemplate<T>;
public:
void f() { /* Same as above */ }
}
template<typename T>
class Derived1 : public Base<Derived1<T>>
// Automatically gets the template. Also means it's harder to use Base<> wrong.
{
};
或者您可以使用rebind
类型特征:
template<typename ToRebind, typename... NewTypes>
struct rebind;
template<template<typename...> class Template, typename... CurrentTypes, typename... NewTypes>
struct rebind<Template<CurrentTypes...>, NewTypes...> {
using type = Template<NewTypes...>;
}
// Used like
TDerivedClass b;
typename rebind<TDerivedClass, int>::type c;