如何在模板化类的'namespace'中创建非模板化类型定义?

How do I make non-templated typedefs in the 'namespace' of a templated class?

本文关键字:创建 类型 定义 namespace      更新时间:2023-10-16

假设我有这样一个类:

template <typename T> class A {
    T datum;
    void foo();
}

我想用下面的类型定义和方法来扩展我的类:

typedef enum {Red, Green, Blue} Color;
bar(Color color) { baz(datum,color); };

问题是,我希望Color只在类中定义,而不是被模板化,也就是说,我希望能够做到:

A<int> a;
a.bar(A::Red);

现在,我不能这样做:

template <typename T> class A {
    typedef enum {Red, Green, Blue} Color;
    // ...
}

因为它定义了不同T的A<T>::Color,而不是A::Color。这:

namespace A {
    typedef enum {Red, Green, Blue} Color;
}
template <typename T> class A { /* ... */ }

似乎无法编译。

typedef enum {Red, Green, Blue} A::Color;
template <typename A> class A { /* ... */ }

那么,我能以某种方式定义A::Color吗?

EDIT

注释后:

我认为你能得到的最好的东西是这样的:

template<typename T = void> class A;
template<> class A<void>{
public:
    enum Color { Red };
};
template <typename T> class A : public A<>{
      T datum;
public:
      void foo(){}
      void bar(Color c){}
};
int main()
{
     A<int> a;
     a.bar(A<>::Red);
}

这有点棘手,但它所做的就是定义一个碱class A<void>,你也可以称之为class A<>,它只包含enum。然后让所有其他模板专门化都继承这个类。

我认为这是最接近你正在寻找的匹配,即一个类作用域的非模板enum


原始回答

恐怕你必须定义一个包含enum定义的非模板基类,然后让你的模板类从这个基类继承。

class A_base{
public:
    typedef enum {Red, Green, Blue} Color;
    void bar(Color color){}
};
template <typename T> class A : public A_base{
     T datum;
     void foo(){}
};
int main()
{
    A<int> a;
    a.bar(A_base::Red);
}

这将而不是enum带入名为A的作用域;但它会使枚举,更重要的是,void bar(Color color)函数非模板化。