Thomas B.
Thomas B.

Reputation: 63

Partial template member specialisation for arrays

I'm trying to have a template class for different data types:

template <typename TDataType>
class CBaseProperty : public CBasePropertyBase

now this class has a specialisation for arrays like this:

template <typename TDataType, u32 TSize>
class CBaseProperty<TDataType[TSize]> : public CBasePropertyBase

now i want to write a specialised version of specific member function for strings:

template <> b8 CBaseProperty<string>::setValue(const void* _pVal)

as soon as i try to specify this member for my partial specialisation of arrays for strings:

template <u32 _TSize> b8 CBaseProperty<string[TSize]>::setValue(const void* _pVal)

i get 3 errors:

Error 1 error C3860: template argument list following class template name must list parameters in the order used in template parameter list

Error 2 error C2995: b8 CBaseProperty<TDataType>::setValue(const void*) : function template has already been defined

Error 3 error C3855: CBaseProperty<TDataType>: template parameter TDataType is incompatible with the declaration

What am i doing wrong? According to all my sources my syntax is correct for a partial member specialisation.

Thanks for any help.

Upvotes: 3

Views: 675

Answers (2)

quantdev
quantdev

Reputation: 23793

You can only specialize a single member function by providing all template arguments (you left the length as an argument), it would force you here to specify the array length.

So if you need a specialized version for arrays of strings, leaving the length as a parameter, you need a specialization of the class template for array of strings first.

As far as I understand your post, the solution can be reduced to the following minimal example :

template<class T>
class foo
{
    public:
    void tell() { cout << "general\n"; }
    void base() { cout << "ok"; }
};

template<class T, std::size_t N>
class foo<T[N]>
{
    public:
    void tell() { cout << "special arrays\n"; }
};

template<std::size_t N>
class foo<std::string[N]>
{
    public:
    void tell() { cout << "special string arrays\n"; }
};

template<>
void foo<std::string>::tell()
{
  cout << "string\n";   
}

int main()
{
  foo<std::string[2]> f;   
  f.tell();

  return 0;
}

Output:

special string arrays

Upvotes: 2

odinthenerd
odinthenerd

Reputation: 5552

template <u32 _TSize> b8 CBaseProperty<string[TSize]>::setValue(const void* _pVal)

this is not valid code when string is an alias for std::string because std::string is variable in length so you can specialize on its length at compile time

template <typename TDataType, u32 TSize>
class CBaseProperty<TDataType[TSize]> : public CBasePropertyBase

this could work but is risky because what type std::size_t is is implementation defined so if the type of your u32 (which you said in your comment is unsigned int) is not the same as std::size_t it may not match.

see live example: http://ideone.com/ZH4v6x

Upvotes: 0

Related Questions