31

I am trying to port the following code. I know the standard doesn't allow explicit specialization in non-namescape scope and I should use overloading, but I just can't find a way to apply this technique in this particular case.

class VarData
{
public:
    template < typename T > bool IsTypeOf (int index) const
    {
        return IsTypeOf_f<T>::IsTypeOf(this, index); // no error...
    }

    template <> bool IsTypeOf < int > (int index) const // error: explicit specialization in non-namespace scope 'class StateData'
    {
        return false;
    }

    template <> bool IsTypeOf < double > (int index) const // error: explicit specialization in non-namespace scope 'class StateData'
    {
        return false;
    }
};
Ryan
  • 1,451
  • 2
  • 27
  • 36
  • possible duplicate of [Explicit specialization in non-namespace scope](http://stackoverflow.com/questions/3052579/explicit-specialization-in-non-namespace-scope) – Jacob Jan 05 '12 at 04:08

2 Answers2

52

You just have to move your specializations of the member templates outside of the class body.

class VarData
{
public:
    template < typename T > bool IsTypeOf (int index) const
    {
        return IsTypeOf_f<T>::IsTypeOf(this, index);
    }
};

template <> bool VarData::IsTypeOf < int > (int index) const
{
    return false;
}

template <> bool VarData::IsTypeOf < double > (int index) const
{
    return false;
}
chrisaycock
  • 36,470
  • 14
  • 88
  • 125
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Much obliged, Charles & Nawaz! I didn't think the VarData::IsTypeOf declaration would work... – Ryan Apr 25 '11 at 10:15
  • 33
    I should add, that it is very important to add the inline keyword for the functions, which are declared outside of the class scope, at least if template class functions are defined in a header file. Otherwise linker won't work... – Ryan May 05 '11 at 06:37
  • 3
    @Ryan sd you mean the correct specialization should be written `template <> inline bool VarData::IsTypeOf < int > (int index) const{return false;}` and `template <> inline bool VarData::IsTypeOf < double > (int index) const{return false;}` ? – Stephane Rolland Jan 31 '13 at 09:30
  • I was facing the same issue strangely without inline i still get compilation error but with inline its compiling fine @Ryan. Thanks for this tip. – Jack Mar 21 '19 at 08:50
6

Define the specialization outside the class as:

template <> 
bool VarData::IsTypeOf < int > (int index) const 
{  //^^^^^^^^^ don't forget this! 
     return false;
}

template <> 
bool VarData::IsTypeOf < double > (int index) const 
{   //^^^^^^^ don't forget this!
     return false;
}
Nawaz
  • 353,942
  • 115
  • 666
  • 851