简体   繁体   English

模板专业化和继承模板类

[英]Template specialization and inheritance template class from other template class

I have some questions about next code: 我对下一个代码有一些疑问:

template<typename T>
class Base;

template<typename T, typename P>
class Base<T(P)> {

};

template<typename T>
class Derived;

template<typename T, typename P>
class Derived<T(P)> : public Base<T(P)> {

};
  1. Class specialization Derived<T(P)> inherits from class template<typename T> class Base or from class template<typename T, typename P> class Base<T(P)> ? 类特化Derived<T(P)>从类template<typename T> class Base继承,还是从类template<typename T, typename P> class Base<T(P)>继承?

  2. What the name of when I'm binding template parameters T and P of class specialization Derived<T(P)> with template parameter T of class Base . 当我将类专业化模板参数TPclass Base模板参数T绑定在一起时的名称是Derived<T(P)>

  1. A class instantiated from the template Derived<T(P)> inherits from the class instantiated from Base<T(P)> . 从模板Derived<T(P)>实例化的类继承自Base<T(P)>实例化的类。 Since the type T(P) matches your Base partial specialization, that template will be used to instantiate the class to inherit from. 由于类型T(P)与您的Base局部专业化匹配,因此该模板将用于实例化要继承的类。

  2. It's just called inheritance. 这就是所谓的继承。 There's nothing special going on there. 那里没有什么特别的事情。 You're just instantiating the template Base with the type T(P) and inheriting from the resulting class. 您只需实例化类型为T(P) Base模板并从生成的类继承即可。


Base<T(P)> will get instantiated when Derived<T(P)> gets instantiated, so Derived<void(int)> inherits from Base<void(int)> . 实例化Derived<T(P)>时将实例化Base<T(P)> ,因此Derived<void(int)>继承自Base<void(int)> Both of those instantiations will go through the same set of rules to figure out which template to use to instantiate that class. 这两个实例化都将遵循相同的规则集,以找出用于实例化该类的模板。

You may be getting confused thinking that T(P) is some special template thing. 您可能会感到困惑,认为T(P)是一些特殊的模板。 It is not. 它不是。 It's just the type "function that returns T and takes a single argument of type P ". 只是类型“返回T并接受类型P的单个参数的函数”。 Granted, types like that don't come up much outside of templates, but they're perfectly legal other places. 当然,类似的类型在模板之外不会出现太多,但是在其他地方它们是完全合法的。 ie

using FuncType = void(int);

// These two declarations are exactly the same
void doAThing(FuncType* callback);
void doAThing(void(*callback)(int));
  1. Class specialization Derived<T(P)> inherits from class template<typename T> class Base or from class template<typename T, typename P> class Base<T(P)> ? 类特化Derived<T(P)>从类template<typename T> class Base继承,还是从类template<typename T, typename P> class Base<T(P)>继承?

Technically, neither. 从技术上讲,两者都没有。 A class or class template never inherits from a template, only from one specific base class type. 类或类模板永远不会从模板继承,而只能从一种特定的基类类型继承。 That is, Derived<int(float&)> inherits Base<int(float&)> , and so on. 也就是说, Derived<int(float&)>继承Base<int(float&)> ,依此类推。 That base class gets instantiated from whatever is the most specialized declaration associated with Base for those specific types. 对于那些特定类型,该基类将从与Base相关的最专门的声明中实例化。 The importance of this distinction comes up if there are additional partial specializations or explicit specializations. 如果存在其他部分专业化或显式专业化,则这种区别的重要性就会显现。

If I change your example a bit, 如果我稍微改变一下你的榜样,

template<typename T> // #1
class Base;

template<typename T, typename P> // #2
class Base<T(P)> {
public:
    static const int mem1 = 1;
};

template<typename T>
class Derived;

template<typename T, typename P>
class Derived<T(P)> : public Base<T(P)> {
};

class SomethingElse {};

template<typename P> // #3
class Base<SomethingElse(const P&)> {
public:
    static const long long mem2 = 2;
};

using ThingType = Derived<SomethingElse(const std::string&)>;
const auto A = ThingType::mem1; // Error!
const auto B = ThingType::mem2; // OK

It's not correct to say that partial specialization Derived<T(P)> inherits partial specialization Base<T(P)> , since the example type Derived<SomethingElse(const std::string&)> uses that Derived partial specialization, but doesn't use that Base partial specialization at all. 说部分专业化Derived<T(P)>继承了部分专业化Base<T(P)>是不正确的,因为示例类型Derived<SomethingElse(const std::string&)>使用了Derived部分专业化,但是没有。完全不使用Base偏专业化。 Base<T(P)> just means the template called Base , with whatever specialization definition for Base best matches the template argument T(P) . Base<T(P)>只是意味着称为Base的模板,其中任何针对Base定义都与模板参数T(P)最匹配。 The decision about what the base class Base<T(P)> means is made independently for each specific set of template arguments when each specialization of Derived is instantiated. 当实例化Derived每个特殊化时,将针对每个特定的模板参数集独立做出关于基类Base<T(P)>含义的决定。

  1. What the name of when I'm binding template parameters T and P of class specialization Derived<T(P)> with template parameter T of class Base. 什么时候我绑定模板参数的名称TP类专业化的Derived<T(P)>与模板参数T阶级基础。

I don't know of any term for this, other than that you are using a dependent compound type. 除了您使用从属化合物类型之外,我对此一无所知。 (Dependent = depends on one or more template parameters; Compound = the type T(P) involves the other types T and P .) This also makes Base<T(P)> a dependent base class in the definition of Derived<T(P)> , meaning the compiler will not look there for plain identifiers, and you need to use this->name or Base::name to make such names valid. (从属=取决于一个或多个模板参数;化合物=类型T(P)涉及其他类型TP )这也使Base<T(P)>Derived<T(P)> ,这意味着编译器将不会在此处查找普通标识符,并且您需要使用this->nameBase::name来使此类名称有效。 It's also important that the template parameters are in "deducible contexts" within the specialization's template arguments. 模板参数位于专业化模板参数内的“可推断上下文”中也很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM