模板专业化和继承模板 class 来自其他模板 class
Template specialization and inheritance template class from other template class
我对下一个代码有一些疑问:
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 特化 Derived<T(P)>
继承自 class template<typename T> class Base
或 class template<typename T, typename P> class Base<T(P)>
?
当我绑定模板参数 T
和 class 专业化 Derived<T(P)>
的 P
与模板参数 [=16] 时的名称是什么=] class Base
.
从模板 Derived<T(P)>
实例化的 class 继承自 Base<T(P)>
实例化的 class。由于类型 T(P)
与您的 Base
部分特化相匹配,该模板将用于实例化要继承的 class。
就叫继承。那里没有什么特别的。您只是用类型 T(P)
实例化模板 Base
并从生成的 class.
继承
Base<T(P)>
会在Derived<T(P)>
被实例化时被实例化,所以Derived<void(int)>
继承自Base<void(int)>
。这两个实例化都将通过同一组规则来确定使用哪个模板来实例化 class.
您可能会感到困惑,认为 T(P)
是一些特殊的模板。它不是。就是"function that returns T
and takes a single argument of type P
"这种类型。诚然,像这样的类型在模板之外很少出现,但它们在其他地方是完全合法的。即
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 class template<typename T> class Base
or from class template<typename T, typename P> class Base<T(P)>
?
从技术上讲,两者都不是。 class 或 class 模板从不继承自模板,仅继承自一种特定的基础 class 类型。即Derived<int(float&)>
继承Base<int(float&)>
,以此类推。该基础 class 从与这些特定类型的 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)
最匹配。当 Derived
的每个特化被实例化时,关于基础 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.
除了您使用的是依赖复合类型外,我不知道有任何其他术语。 (dependent = 依赖于一个或多个模板参数;Compound = 类型 T(P)
涉及其他类型 T
和 P
。)这也使 Base<T(P)>
成为依赖基 class 在 Derived<T(P)>
的定义中,意味着编译器不会在那里寻找普通标识符,您需要使用 this->name
或 Base::name
使这些名称有效。同样重要的是,模板参数位于专业化模板参数中的 "deducible contexts" 中。
我对下一个代码有一些疑问:
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 特化
Derived<T(P)>
继承自 classtemplate<typename T> class Base
或 classtemplate<typename T, typename P> class Base<T(P)>
?当我绑定模板参数
T
和 class 专业化Derived<T(P)>
的P
与模板参数 [=16] 时的名称是什么=]class Base
.
从模板
Derived<T(P)>
实例化的 class 继承自Base<T(P)>
实例化的 class。由于类型T(P)
与您的Base
部分特化相匹配,该模板将用于实例化要继承的 class。就叫继承。那里没有什么特别的。您只是用类型
T(P)
实例化模板Base
并从生成的 class. 继承
Base<T(P)>
会在Derived<T(P)>
被实例化时被实例化,所以Derived<void(int)>
继承自Base<void(int)>
。这两个实例化都将通过同一组规则来确定使用哪个模板来实例化 class.
您可能会感到困惑,认为 T(P)
是一些特殊的模板。它不是。就是"function that returns T
and takes a single argument of type P
"这种类型。诚然,像这样的类型在模板之外很少出现,但它们在其他地方是完全合法的。即
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)>
?
从技术上讲,两者都不是。 class 或 class 模板从不继承自模板,仅继承自一种特定的基础 class 类型。即Derived<int(float&)>
继承Base<int(float&)>
,以此类推。该基础 class 从与这些特定类型的 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)
最匹配。当 Derived
的每个特化被实例化时,关于基础 class 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.
除了您使用的是依赖复合类型外,我不知道有任何其他术语。 (dependent = 依赖于一个或多个模板参数;Compound = 类型 T(P)
涉及其他类型 T
和 P
。)这也使 Base<T(P)>
成为依赖基 class 在 Derived<T(P)>
的定义中,意味着编译器不会在那里寻找普通标识符,您需要使用 this->name
或 Base::name
使这些名称有效。同样重要的是,模板参数位于专业化模板参数中的 "deducible contexts" 中。