如何在模板化类的“命名空间”中创建非模板化的typedef?

时间:2015-07-17 07:34:40

标签: c++ templates namespaces scope

假设我有这门课程:

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

我想用以下typedef和方法扩充我的类:

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吗?

1 个答案:

答案 0 :(得分:4)

修改

comment之后:

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

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)非模板化。