Gostaria de ter um conceito que verifica se um tipo é um contêiner de comprimento fixo. O tipo pode ser um array estilo C, um std::array
, a std::span
ou um contêiner personalizado. Posso verificar a condição do contêiner conforme mostrado no código abaixo, mas não consigo fazer com que ele verifique a condição de comprimento.
template <typename T, size_t N>
concept fixed_container =
requires (T const& t)
{
{std::size(t)} -> std::same_as<size_t>;
{std::begin(t)};
{std::end(t)};
}
// && std::declval<T>().size() == N // Error: 'declval() must not be used!'
// && T::size() == N // Error: 'call to non-static member function without an object argument'
;
// These should all be correct
static_assert( fixed_container<std::array<double, 3>, 3>);
static_assert(!fixed_container<std::array<double, 3>, 4>);
static_assert( fixed_container<std::span<double, 3>, 3>);
static_assert(!fixed_container<std::span<double, 3>, 4>);
static_assert( fixed_container<double[3], 3>);
static_assert(!fixed_container<double[3], 4>);
Alguma ideia?
EDIT: O bloco
requires (T const& t)
{
{std::size(t)} -> std::same_as<size_t>;
{std::begin(t)};
{std::end(t)};
}
pode ser substituído por uma única linha
std::ranges::sized_range<T>
Você precisará lidar com isso separadamente. Por exemplo, você pode fazer o seguinte ( Que é inspirado por uma pergunta semelhante mencionada nos comentários ):
Veja a demonstração ao vivo