Pergunta

So I have this class

template<typename T, std::size_t Columns, std::size_t Rows>
class mat_base;

And I have this specialization

template<typename T, std::size_t ColumnsRows>
class mat_base<T, ColumnsRows, ColumnsRows>;

and whenever I try to use this partial specialization for a return type or variable I get an error that I haven't supplied enough template parameters :(

Heres an example of my usage that fails saying not enough arguments:

template<typename T, std::size_t ColumnsRows>
mat_base<T, ColumnsRows> transpose(const mat_base<T, ColumnsRows> &lhs, const mat_base<T, ColumnsRows> &rhs);

Where as if I replace every instance of mat_base<T, ColumnsRows> with mat_base<T, ColumnsRows, ColumnsRows> it works fine.

What exactly is my issue in this? What am I not understanding correctly here?

Foi útil?

Solução

You cannot ever refer to a template partial specialisation. You have to refer to the template, and if it matches the partial specialisation, the partial specialisation will be used.

After

template <typename T>
struct S;

template<>
struct S<int> { };

you wouldn't expect to be able to refer to S<> (without specifying int), would you?

After

template <typename T>
struct S;

template <typename T>
struct S<T *> { };

you would expect S<int *> to match the partial specialisation with T = int, not with T = int *, right?

There is no difference here. If a template has three parameters, you need three arguments to be able to use the template.

Outras dicas

If you want the second and third template arguments to be exactly same, then you could use template alias instead of partial specialization (because the latter is not meant for that):

template<typename T, std::size_t ColumnsRows>
using mat_base_t = mat_base<T, ColumnsRows, ColumnsRows>;

Now use mat_base_t instead of mat_base if you want to pass only two arguments (instead of three), as shown below:

template<typename T, std::size_t ColumnsRows>
mat_base_t<T, ColumnsRows> transpose(const mat_base_t<T, ColumnsRows> & lhs, 
                                     const mat_base_t<T, ColumnsRows> & rhs);

Or use default value for third argument of the mat_base class template, as @Dieter Lücking said in his answer.

Note that (partial) specialization is selected by the compiler (not you) if the argument(s) passed to the template matches the pattern specified by the specialization. That has a different use case. Your case seems to be different.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top