3
votes

I cant figure out how to specialize partially this template. compiler complains that template parameter N is not used in partial specialization

#include <boost/multi_array.hpp>

template<typename T, class A>
struct adaptable;

template<typename T, size_t N>
struct adaptable<T,
                 // line below is the problem
                 typename boost::multi_array<T,N>::template array_view<2>::type>
{
    typedef typename boost::multi_array<T,N>::template array_view<2>::type type;
};

I can add dummy template parameter just to silence compiler.

template<typename T, class A, class A0 = A>
struct adaptable;

template<typename T, size_t N>
struct adaptable<T,
                 typename boost::multi_array<T,N>::template array_view<2>::type,
                 boost::multi_array<T,N> >
{
    typedef typename boost::multi_array<T,N>::template array_view<2>::type type;
};

is there more straightforward way?

1
I can't even tell what you're trying to accomplish with your partial specialization. What's the non-specialized version of struct adapatable look like?Omnifarious
@Onm I put nonspecialized declarationAnycorn
I'm not certain, but there could be problems stemming from the fact that in the base template for adaptable, the 2nd template parameter is a type, while in your specialisation, it is an integral constant. My guess is that for that reason, the 2nd declaration is not actually a specialisation (partial or otherwise) of the 1st, and should probably be flagged by the compiler as an error.j_random_hacker
@j_random_hacker: the same thing happens even if all parameters are types - it's just that the relationship between the specialized value of A and N is apparently too obscure to be allowed. An analogue with types is the way that you can specialize a template<class T> struct X for T of the form vector<U> (for all U) but not for T of the form vector<U>::iterator. And of course the same thing is true when deducing the template arguments of functions, though I don't know enough C++ to say whether the rules are exactly the same :)Mike Dinsdale
@Mike: I think you're right on the money there. typename boost::multi_array<T,N>::template array_view<2>::type is a "non-deduced context" for N. Although it seems like if you were to try to instantiate adaptable<float, typename boost::multi_array<float,42>::template array_view<2>::type>, the compiler should be able to deduce N = 42, it makes sense to forbid this type of deduction because in general it (a) doesn't necessarily have a unique answer (e.g. N = 123 might also give the same ultimate type) and (b) even if it does, that unique answer could be extremely hard to find.j_random_hacker

1 Answers

3
votes

I don't see anything in your example that looks like partial specialization. A partial specialization is a specialization that specifies exact types for some if the base template parameters, but leaves others open. For example:

template <class T, class U>
struct my_template {    
     // the base template where both T and U are generic
};

template <class T>
struct my_template<int> { 
    // A partial specialization where T is still generic, but U == int
};

To support partial specialization, the base template has to have at least two template parameters (call the number N). The partially specialized template can have 1..N-1 template parameters. The partial specialization must be located where the compiler will already have "seen" the base template before attempting to compile the partial specialization. The partial specialization is written as a completely separate template from the base template (though the base template and all specializations must have the same name, of course).