Brett-Michael Green Brett-Michael Green - 2 months ago 6
C++ Question

Trouble with Templates: 'class' type redifinition

#pragma once
//includes
template<class RefType>
class Foo
{
public:

template<>
enum Foo<QString>::bar { //values A }; //LINE X
template<>
enum Foo<double>::bar { //values B };
template<>
enum Foo<Kraken::Point3>::bar { //values C };
//functions
}; //LINE Y


compiler gives the error for LINE X

error C2011: 'Foo<QString>': 'class' type redefinition


with the notes

note: see declaration of 'Foo<QString>' LINE X
note: note: see reference to class template instantiation 'Foo<RefType>'LINE Y


I do not understand the source of this error, if I become more enlightened towards the problem I will reformat the question to become clearer

Answer

If you want to have different enum's for chosen types, you should specialize your template class with these types:

template<class RefType>
class Foo
{
    //default enum if you want
};

template<>
class Foo<QString>
{
    enum bar {Q1, Q2, Q3};    
};

template<>
class Foo<double>
{
    enum bar {d1, d2, d3};    
};

template<>
class Foo<Kraken::Point3>
{
    enum bar {K1, K2, K3};    
};

Your code looks like you want to specialize just some members of class template, but that is not possible in C++.

One way to hack this, while preserving most of class structure, is public inheritance of general class implementation:

template<class Reftype>
class FooImpl
{
    RefType x;
public:
    void set_x(RefType val) {x=val;}
    RefType get_x(void) {return x;}
};

template<class RefType>
class Foo : public FooImpl<Reftype>
{

};

template<>
class Foo<QString> : public FooImpl<QString>
{
    enum bar {Q1, Q2, Q3};    
};

template<>
class Foo<double> : public FooImpl<double>
{
    enum bar {d1, d2, d3};    
};

template<>
class Foo<Kraken::Point3> : public FooImpl<Kraken::Point3>
{
    enum bar {K1, K2, K3};    
};

This way you don't have to redefine all class members just because you wanted different enums in specializations.