1
votes

I'm working with VS 2008 (sorry, can't update). I need template specialization for my list class. The argument I want to specialize is a member function pointer.

In short, how can I make the following code work (I can' use variadic templates):

// two or three args
template <typename T1, typename T2, void (T1::* FUNC)(const T2&) = 0> struct list;
// specialized code for 2 args.
template <typename T1, typename T2> struct list<T1, T2> { };

The error message is:

C2754: 'specialization' : a partial specialization cannot have a dependent non-type template parameter

Maybe there is no solution for my problem. But that also an answer.

Thanks for your help in advance.

1
This might be one of those instances where you would use a delegate. msdn.microsoft.com/en-us/library/213x8e7w%28v=vs.90%29.aspxTebc
why do you need that specialization? the primary template has a default argument, meaning you can omit it. what would you like to achieve?Andy Prowl
If the member function pointer is null I have to implement a complete different list class. And would like to separate these two implementation to have clean code (no if ... else).zussel
@Tebc I don't want to mix it with c# because the code needs to run under linux as well and should be native c++. Sorry.zussel

1 Answers

2
votes

If I do understand correctly what you are trying to achieve, it cannot be done. Let's consider an even simpler case of illegal specialization:

template <typename T1, typename T2, void (T1::* FUNC)(const T2&)> struct list;
template <typename T1, typename T2> struct list<T1, T2, 0> { };

Here you always have to supply three arguments to instantiate your template, and you try to specialize the primary template for the case where the last argument is a null pointer.

Per § 14.5.5/8 of the C++ Standard:

"The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [ Example:

template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error

template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error

—end example ]"

You cannot specialize a non-type argument whose type is dependent on other types in the template parameter list. Thus, the above specialization is illegal.

Your original design is just a particular case of this specialization, where the last (non-type) parameter has a default argument value, which you omit in the specialization (omitting it is legitimate per se). The reason why this is illegal is not related with the presence of a default argument, but rather with the fact that you are trying to specialize a non-type argument that has a dependent type.