Не так хорошо, как другое решение, но я хотел показать, что это возможно (даже если досадно) в C ++ 11 (опираясь на решение @ KonradRudolph)
Редактировать: Это также просто C ++ 14, поскольку с тех пор std::get
составляет всего constexpr
. Страница на нем в cppref сбивает с толку, но с тех пор исправлена.
#include <array>
#include <type_traits>
template<typename T, std::size_t N, std::size_t from>
constexpr typename std::enable_if<from == N, bool>::type
is_sorted_impl(std::array<T, N> const &arr)
{
return true;
}
template<typename T, std::size_t N, std::size_t from,
class = typename std::enable_if<from<N>::type>
constexpr bool is_sorted_impl(std::array<T, N> const &arr)
{
return N - from == 0 or (std::get<from - 1>(arr) <= std::get<from>(arr) and
is_sorted_impl<T, N, from + 1>(arr));
}
template<typename T, std::size_t N>
constexpr bool is_sorted(std::array<T, N> const &arr)
{
return N == 0 or is_sorted_impl<T, N, 1>(arr);
}
int main()
{
constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
static_assert(is_sorted(arr), "test");
}
Мы используем std::get
, что было constexpr
с момента ее появления в C ++ 14 , Чтобы обойти создание экземпляра std::get<N>
(который, очевидно, дает ошибку времени компиляции), мы специализируем шаблон функции для случая from == N
(что нам нужно сделать с enable_if
, поскольку частичные специализации шаблона функции не допускаются). Не очень хорошо, но возможно.
С другой стороны: решение @ KonradRudolph компилируется в g cc и также включается -std=c++11 -pedantic
, хотя это не должно быть из-за того, что operator[]
не является constexpr
, это ошибка?