I would like to use a template class to provide some common functionality to some child classes that are very similar. The only variation is the enumeration that each uses.
This is the parent class
template<typename T> class E_EnumerationBase : public SimpleElement { public: E_EnumerationBase(); virtual bool setValue(QString choice); virtual T getState(); protected: T state; QHash<QString, T> dictionary; }; template<typename T> E_EnumerationBase<T>::E_EnumerationBase() { state = 0; } template<typename T> bool E_EnumerationBase<T>::setValue(QString choice) { T temp; temp = dictionary.value(choice, 0); if (temp == 0) { return false; } value = choice; state = temp; return true; } template<typename T> T E_EnumerationBase<T>::getState() { return state; }
This is one of the children
enum TableEventEnum { NO_VALUE = 0, ATTRACT = 1, OPEN = 2, CLOSED = 3 }; class E_TableEvent : public E_EnumerationBase<enum TableEventEnum> { public: E_TableEvent(); };
This is the constructor
E_TableEvent::E_TableEvent() { state = NO_VALUE; dictionary.insert("attract", ATTRACT); dictionary.insert("open", OPEN); dictionary.insert("closed", CLOSED); }
The linker is throwing this error:
e_tableevent.cpp:6: error: undefined reference to `E_EnumerationBase<TableEventEnum>::E_EnumerationBase()'
Can an enumeration be used as the parameter to a template like this?
Yes, the compiler will even iterate through strings for us at compile time and compare character values! Here, IsValid() is called once for each enum value template parameter (of type E ) after typename E . Writing the template parameters in this way, <typename E, E A, E...
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.
Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.
Enumerations can be template parameters in exactly the same way that ints can.
enum Enum { ALPHA, BETA }; template <Enum E> class Foo { // ... }; template <> void Foo <ALPHA> :: foo () { // specialise } class Bar : public Foo <BETA> { // OK }
But you simply haven't provided a definition for E_EnumerationBase::E_EnumerationBase()
This isn't a problem with templates or inheritence. It's the same as if you written this:
struct Foo { Foo (); } int main () { Foo foo; }
The syntax goes for value arguments like it is for typename arguments. Basically, you just replace typename
with the name of your enum
:
enum Foo { Bar, Frob }; template <Foo F> struct Boom {}; // primary template template <> struct Boom<Bar> {}; // specialization of whole class ... template <> void Boom<Frob>::somefun() {} // specialization of single member
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With