2

Suppose I have this class:

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

I want to augment my class with the following typedef and method:

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

The thing is, I want Color to only be defined within the class, yet not be templated, i.e. I want to be able to do:

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

Now, I can't do this:

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

since it defines A<T>::Color for different T's, not A::Color. And this:

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

doesn't seem to compile. Neither does this:

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

So, can I get an A::Color defined somehow?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • http://stackoverflow.com/questions/16891700/c-non-template-method-in-template-class http://stackoverflow.com/questions/27325794/non-template-function-in-a-template-class – Piotr Siupa Jul 17 '15 at 07:37

1 Answers1

4

EDIT

After the comment:

I think the best you can get is something along these lines:

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);
}

It's a bit tricky, but all it does is to define a base class A<void>, that you can call also class A<>, that just contains the enum. Then you make all other template specialization inherit from this class.

I think it's the closest match to what you're looking for, i.e. a class scoped non-template enum.


ORIGINAL ANSWER

I'm afraid you'll have to define a non template base class containing the definition of the enum, and then let your template class inherit from this base.

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);
}

This will not bring the enum into a scope named A; but it will make the enum and, more important, the function void bar(Color color) non-templated.

Community
  • 1
  • 1
Paolo M
  • 12,403
  • 6
  • 52
  • 73