действительно ли алгоритм constexpr полезен, когда итератор (входные параметры) вообще не constexpr?

предложенный в C++ 20, некоторые алгоритмы constexpr.

например:

template< class InputIt, class UnaryPredicate >
bool all_of( InputIt first, InputIt last, UnaryPredicate p );
(since C++11)
(until C++20)


template< class InputIt, class UnaryPredicate >
constexpr bool all_of( InputIt first, InputIt last, UnaryPredicate p );
(since C++20)

хотя мы знаем, что итератор не constexpr вообще. Я считаю, что это полезно только в случае контейнера пользователем. Может ли кто-нибудь уточнить, если я что-то упускаю и правильно ли мое понимание ?.

1 ответов


конечно. Попробуем другой алгоритм, которого пока нет constexpr В C++20, насколько мне известно,std::iota. Но это не слишком трудно определить constexpr версия (я только что скопировал пример реализации из cppreference и ударил constexpr на это):

template<class ForwardIterator, class T>
constexpr void my_iota(ForwardIterator first, ForwardIterator last, T value)
{
    while(first != last) {
        *first++ = value;
        ++value;
    }
}

так это полезно? Да. Пока итераторы создаются как часть оценки постоянного выражения, оценка алгоритма может отображаться в постоянном выражении. Для пример:

template<std::side_t N, typename T>
constexpr make_iota_array(T start = {}) {
  std::array<T, N> ret{};
  my_iota(ret.begin(), ret.end(), start);
  return ret;
}

вышеизложенное создает массив, инициализированный алгоритмом iota. Если функция вызывается как часть вычисления постоянного выражения, то объект ret создается как часть оценки, а также его итераторы. Они действительны:

constexpr auto a1 = make_iota_array<10, int>();
constexpr auto a2 = make_iota_array<10>(0u);