【问题标题】:member template specialization and its scope成员模板专业化及其范围
【发布时间】:2010-10-22 22:41:03
【问题描述】:
在我看来,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.
}
我的问题是为什么不允许这样做?
【问题讨论】:
标签:
c++
templates
scope
specialization
【解决方案1】:
我的问题是为什么不允许这样做?
从我的草稿副本看来,以下内容提出了上述限制:
在
类模板、类模板成员或类成员的显式特化声明
模板,明确特化的类的名称应为 simple-template-id。
解决方法是专门化封闭类。
【解决方案2】:
我明白你想要做什么,但你做得不对。试试这个:
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;
};
【解决方案3】:
我将“忽略”标准规范并尝试一个合乎逻辑的论点:
如果你有两个班级:
class A
{
struct S { };
};
class B: public A
{
struct S { };
};
A::S 和 B::S 是两种不同的类型。将逻辑扩展到模板特化,当您尝试通过派生类中的内部类来特化在基类中声明的内部类时,您实际上是在尝试定义一个不同的类型,具有相同的名称(但另一个命名范围)。