Peter Moran
Peter Moran

Reputation: 313

"Overload" a template based on the number of template arguments

I am making a template to help make 2-dimensional arrays (matricies). Right now, it is simply an alias of std::arrays inside a std::array, which I like because it keeps the size as part of the type (this will help with compile time checks later on.

template <class T, size_t Rows, size_t Columns>
using Matrix = std::array<std::array<T, Columns>, Rows>;

I would like to optionally omit T and have it default to double since the common case will be for doubles.

I realize that the normal method for defaulting a template argument is to put it at the end, however, to match the std::array API, I would like to avoid using template <size_t Rows, size_t Columns, class T = double>.

I tried the following, hopping the compiler could select by the number of template arguments, but it failed with "conflicting declaration of template".

template <class T, size_t Rows, size_t Columns>
using Matrix = std::array<std::array<T, Columns>, Rows>;

template <size_t Rows, size_t Columns>
using Matrix = std::array<std::array<double, Columns>, Rows>;

Perhaps there is a fancier way to do this via another template mechanism?

Upvotes: 3

Views: 83

Answers (1)

NathanOliver
NathanOliver

Reputation: 180630

You cannot overload aliases. You can however overload function templates and you could leverage that fact to make a factory function that will create an instance of the class for you. The would give you functions like

template <class T, size_t Rows, size_t Columns>
auto create_matrix() { return std::array<std::array<T, Columns>, Rows>{}; }

template <size_t Rows, size_t Columns>
auto create_matrix() { return std::array<std::array<double, Columns>, Rows>{}; }

and then you use it like

auto double_matrix = create_matrix<2, 4>();
auto float_matrix = create_matrix<float, 2, 4>();

Upvotes: 1

Related Questions