Home > Net >  Can I write a `concept` to accept a specific template class only?
Can I write a `concept` to accept a specific template class only?

Time:10-28

I have a templated class:

template<Vector T>
struct diagonal_matrix;

Now, I want to create a concept DiagonalMatrix for all of templated class versions. So:

 DiagonalMatrix<diagonal_matrix<std::vector<double>>> == true
 DiagonalMatrix<diagonal_matrix<std::array<float, 4>>> == true
 DiagonalMatrix<diagonal_matrix<std::span<int, 10>>> == true
 DiagonalMatrix<diagonal_matrix<my::random_access_container_view<unsigned int>>> == true
 DiagonalMatrix<other_matrix> == false

Keep in mind that diagonal_matrix has a subset of other_matrix functionality.

Is there a way to create a concept DiagonalMatrix which only accepts struct diagonal_matrix<?> without tagging the struct with a static constexpr bool I_am_a_diagonal_matrix = true;?. I don't care for implementations other than struct diagonal_matrix<?>.

CodePudding user response:

Just wrap a plain old type trait:

#include <type_traits>

namespace detail {
    template<typename>
    constexpr bool is_diagonal_matrix_v{};
}

template<typename T>
concept DiagonalMatrix =
    detail::is_diagonal_matrix_v<std::remove_cvref_t<T>>;

Then only types for which detail::is_diagonal_matrix_v<> is appropriately specialized will satisfy (i.e. it is extensible and not strictly limited to diagonal_matrix<>).

Online Demo

CodePudding user response:

If diagonal_matrix has a member aliases for all it's template parameters, you can substitute them into diagonal_matrix<>, then check you get what you started with.

template <typename M>
concept DiagonalMatrix = std::same_as<M, diagonal_matrix<typename M::vector_type>>;
  • Related