[英]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)> {
};
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)>
继承?
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
. 当我将类专业化模板参数
T
和P
与class Base
模板参数T
绑定在一起时的名称是Derived<T(P)>
。
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
局部专业化匹配,因此该模板将用于实例化要继承的类。
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));
- Class specialization
Derived<T(P)>
inherits from classtemplate<typename T> class Base
or from classtemplate<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)>
含义的决定。
- What the name of when I'm binding template parameters
T
andP
of class specializationDerived<T(P)>
with template parameterT
of class Base.什么时候我绑定模板参数的名称
T
和P
类专业化的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)
涉及其他类型T
和P
)这也使Base<T(P)>
在Derived<T(P)>
,这意味着编译器将不会在此处查找普通标识符,并且您需要使用this->name
或Base::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.