没有完全指定的模板作为C ++中的模板参数

时间:2019-06-05 16:50:09

标签: c++ templates

在奇怪的重复模板模式中,我需要将嵌套类型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>>
{

};

2 个答案:

答案 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;