Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is constexpr algorithm really useful, when iterator (input parameters) are not constexpr generally?

Tags:

c++

c++20

proposed in c++ 20, some algorithms are constexpr.

For example:

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)

While we know iterator are not constexpr generally. I think this is useful only in case of constexpr container. Can someone clarify if I am missing something and Whether my understanding is correct ?.

like image 492
code707 Avatar asked Jul 24 '18 05:07

code707


People also ask

What is the point of constexpr functions?

constexpr functions A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.

Can constexpr throw?

Even though try blocks and inline assembly are allowed in constexpr functions, throwing exceptions or executing the assembly is still disallowed in a constant expression.


1 Answers

Sure it is. Let's try another algorithm, which is not yet constexpr in C++20 to my knowledge, std::iota. But it's not too hard to define a constexpr version (I just copied the sample implementation from cppreference and slapped constexpr on it):

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

So is it useful? Yes it is. So long as the iterators are created as part of evaluating a constant expression, the evaluation of the algorithm can appear in a constant expression. For instance:

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;
}

The above creates an array initialized with the iota algorithm. If the function is called as part of evaluating a constant expression, the object ret is created as part of the evaluation, and so are its iterators. These are valid:

constexpr auto a1 = make_iota_array<10, int>();
constexpr auto a2 = make_iota_array<10>(0u);
like image 199
StoryTeller - Unslander Monica Avatar answered Nov 16 '22 04:11

StoryTeller - Unslander Monica