成员模板专业化及其范围
-
03-07-2019 - |
题
在我看来,C ++不允许在命名空间和全局范围之外的任何范围内使用成员模板专门化(MS VSC ++错误C3412)。但对我来说,在派生类中专门化基类的主要成员模板是有意义的,因为这是派生类所做的事情 - 专门化基类中的事物。例如,请考虑以下示例:
struct Base
{
template <class T>
struct Kind
{
typedef T type;
};
};
struct Derived : public Base
{
/* Not Allowed */
using Base::Kind;
template <>
struct Kind <float>
{
typedef double type;
};
};
int main(void)
{
Base::Kind<float>::type f; // float type desired
Derived::Kind<float>::type i; // double type desired but does not work.
}
我的问题是为什么不允许?
解决方案
我得到了你想要做的事情,但你做得不对。试试这个:
struct Base{};
struct Derived{};
// Original definition of Kind
// Will yield an error if Kind is not used properly
template<typename WhatToDo, typename T>
struct Kind
{
};
// definition of Kind for Base selector
template<typename T>
struct Kind<Base, T>
{
typedef T type;
};
// Here is the inheritance you wanted
template<typename T>
struct Kind<Derived, T> : Kind<Base, T>
{
};
// ... and the specialization for float
template<>
struct Kind<Derived, float>
{
typedef double type;
};
其他提示
我的问题是为什么不允许?
从我的草稿副本中可以看出以下内容具有上述限制:
在 类模板的明确专门化声明,类模板的成员或类成员 模板,显式专用的类的名称应为simple-template-id。
解决方法是专门化封闭类。
我会“忽略”标准规范并尝试逻辑论证:
如果你有两个班级:
class A
{
struct S { };
};
class B: public A
{
struct S { };
};
A :: S和B :: S是两种不同的类型。将逻辑扩展到模板特化,当您尝试通过派生类中的内部类来专门化基类中声明的内部类时,实际上是在尝试使用相同的名称(但是另一个命名范围)来定义不同的类型。 / p>
不隶属于 StackOverflow