2
votes

Consider the following c++ code:

template <int K>
struct KData
{
   float data[K];
};

template<int K>
class KClass
{
public:   
    typedef KData<K> Data;
    Data m_data;

    Data square()
    {
        Data result;
        for(int i = 0; i < K; ++i)
            result.data[i] = m_data.data[i] * m_data.data[i];
        return result;
    }
    
    // Specialization for K = 2
    template<>
    KClass<2>::Data square();
};

template<>
KClass<2>::Data KClass<2>::square()
{
   Data result;
   result.data[0] = m_data.data[0] * m_data.data[0];
   result.data[1] = m_data.data[1] * m_data.data[1];
   return result;
}

int main()
{
   KClass<2> c;
   c.m_data.data[0] = c.m_data.data[1] = 1.f;
   c.square();
   
   return 0;
}

It has a the 'KCalss' which has a template data member ('m_data') and a method that performs some computations on that data member ('square()'). What I want to do is to make an specialization of 'square()' for the case when K = 2, for example.

Trying to compile it with 4.6.7 or 4.7.2 gives the following error:

main.cpp:23:14: error: explicit specialization in non-namespace scope 'class KClass'

main.cpp:24:5: error: 'Data' in 'class KClass<2>' does not name a type

Any idea of what I'm doing wrong?

Thanks in advance.

=== EDIT ===

A workaround I found is to declare the second 'square()' method as a template as well:

template<int K2>
typename KClass<K2>::Data square();

It works nicely, but it allows the user to call 'aquare()' passing a template parameter different from the class, e.g:

KClass<2> c;
c.square<3>;

which gives a "undefined reference to" linking error.

=== EDIT (SOLUTION) ===

All right, the solution was simpler than I expected. I just had to remove the template declaration:

template<>
inline KClass<2>::Data square();

, which is unnecessary.

1
VC++ 2010 compiles it okYola

1 Answers

1
votes
template<>
KClass<2>::Data KClass<2>::square()
                ^^^^^^^^
{

And you have to remove this. This is not how you specialize a member function. The member function can not be specialized with in the class scope. It needs to be specialized within the surrounding namespace of the class declaration.

 template<>
 KClass<2>::Data square();