我对下一个代码有疑问:
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)> {
};
类专业化Derived<T(P)>
是从类template<typename T> class Base
还是类template<typename T, typename P> class Base<T(P)>
继承的?
当我将类专业化T
的模板参数P
和Derived<T(P)>
与T
的模板参数class Base
绑定在一起时的名称是什么
答案 0 :(得分:2)
从模板2
实例化的类继承自add
实例化的类。由于类型Derived<T(P)>
与您的Base<T(P)>
部分专业化匹配,因此该模板将用于实例化要继承的类。
这就是所谓的继承。那里没有什么特别的事情。您只需实例化类型为T(P)
的模板Base
并从结果类中继承。
Base
将在T(P)
实例化时被实例化,因此Base<T(P)>
从Derived<T(P)>
继承。这两个实例都将遵循相同的规则集,以找出用于实例化该类的模板。
您可能会感到困惑,认为Derived<void(int)>
是一些特殊的模板。它不是。它只是类型“返回Base<void(int)>
并接受类型为T(P)
的单个参数的函数”。当然,类似的类型在模板之外不会出现太多,但是在其他地方它们是完全合法的。即
T
答案 1 :(得分:2)
- 类专业化
Derived<T(P)>
是从类template<typename T> class Base
还是类template<typename T, typename P> class Base<T(P)>
继承的?
从技术上讲,两者都不是。类或类模板永远不会从模板继承,而只能从一种特定的基类类型继承。也就是说,Derived<int(float&)>
继承了Base<int(float&)>
,依此类推。对于那些特定类型,可以从与Base
相关的最专门的声明中实例化该基类。如果存在其他部分专业化或显式专业化,则这种区别的重要性就会显现。
如果我稍微改变一下您的例子,
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
说部分专业化Derived<T(P)>
继承了部分专业化Base<T(P)>
是不正确的,因为示例类型Derived<SomethingElse(const std::string&)>
使用了Derived
部分专业化,但没有使用它完全Base
部分专业化。 Base<T(P)>
仅表示名为Base
的模板,而Base
的任何特殊化定义都与模板参数T(P)
最匹配。实例化Base<T(P)>
的每个特化后,将针对每个特定的模板参数集独立地决定基类Derived
的含义。
- 我将类特化
T
的模板参数P
和Derived<T(P)>
与Base类的模板参数T
绑定时的名称是什么。
除了您使用从属化合物类型之外,我对此一无所知。 (Dependent =取决于一个或多个模板参数; Compound =类型T(P)
涉及其他类型T
和P
。)这也使Base<T(P)>
在Derived<T(P)>
的定义,这意味着编译器将不会在此处查找普通标识符,并且您需要使用this->name
或Base::name
来使这些名称有效。同样重要的是,模板参数应位于专业化模板参数中的“可推断上下文”中。