未完全指定模板作为模板参数C++

Not fully specified template as template argument in C++

本文关键字:参数 C++      更新时间:2023-10-16

在奇怪的重复模板模式中,我需要将嵌套类型更改为TDerivedClass<T>类型的嵌套类型T。有没有办法通过未完全指定Derived1类来指定Base?像这样的东西: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>>
{
};

您可能需要模板模板参数:

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

您可以专门传递模板类:

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;