Home > Mobile >  Template operator on difference but related types
Template operator on difference but related types

Time:12-17

I am implementing some matrix operations for my templated matrix<T> and matrix_view<T>. At first I had

template <typename T, typename U>
matrix<common_type_t<T, U>> operator (matrix_view<T>, matrix_view<U>);

and expected it to work also for matrix

matrix<int> a, b;
auto c = a   b;

because there is a converting constructor from matrix<T> to matrix_view<T>.

But it didn't work, because of the "Type deduction does not consider implicit conversions" rule.

So I added another overload

template <typename T, typename U>
matrix<common_type_t<T, U>> operator (matrix<T>, matrix<U>);

But the story is still not over, for operator between matrix<T> and matrix_view<T>, I need to define another two overloads to make them work.

Now I wonder if I have to define all four overloads for every matrix operation. That's a lot of boilerplate code. And indeed the number of overloads needed grows exponentially with the number of types involved, if I am to add some other types in the future.

Is there any solution to this problem? Preferably only requiring me to define the first overload.

CodePudding user response:

Use a concept:

template<typename C>
concept matrix_c = requires(C const& c) { [] <typename ... X>(matrix<X ...> const&) {}(c); }
                || requires(C const& c) { [] <typename ... X>(matrix_view<X ...> const&) {}(c); }

auto operator (matrix_c auto&& m1, matrix_c auto&& m2);

This solution will work for all combinations of matrix_view and matrix.

Note that the concept can be simplified if you use, e.g., a common base class matrix_base, as it's usual in expression template code. It'll work, however, also for completely unrelated classes.

  • Related