Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't std::algorithms constexpr and which could be?

Why aren't any std::algorithm methods constexpr? If I understand the new C++14 rules correctly, many of these methods could be constexpr. For example, why can't std::find be constexpr?

static constexpr std::array<char, 4> DnaBases {'A', 'C', 'G', 'T'};  constexpr bool is_dna(char b) {     return std::find(std::cbegin(DnaBases), std::cend(DnaBases), b) != std::cend(DnaBases); // why not? } 

Which other std::algorithms could be constexpr?

like image 782
Daniel Avatar asked Sep 04 '15 10:09

Daniel


People also ask

Why does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.

What is the point of constexpr?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.

Is constexpr always evaluated at compile time?

constexpr functions will be evaluated at compile time when all its arguments are constant expressions and the result is used in a constant expression as well.

Which is false about constexpr?

Short answer: static_assert(false) should never appear in a constexpr if expression, regardless of whether it's in a template function or whether it's in the discarded branch.


2 Answers

It could be constexpr, but cannot be evaluated as a constant expression, since in this case, for example for compile-time find it is required that: begin/end should be constexpr, the * operator of the iterator should be constexpr, operator == should be constexpr, operator != for the iterator should be constexpr, operator ++ for the iterator should be constexpr. But, if all functions are constexpr, then many algorithms can be implemented with constexpr.

You can look at the SPROUT library for the implementation of constexpr containers/algorithms.

And related talk on the isocpp.org forums

like image 140
ForEveR Avatar answered Oct 05 '22 11:10

ForEveR


Functions cannot be overloaded based on constexpr-ness. As a result, any function defined as constexpr needs to be implemented in a form which could be a constexpr. This requirement imposes constraints on all implementations.

The C++14 specification is somewhat relaxed with respect to the constraints compared to C++11. However, when the specification was finalized nobody was confident that all optimizations which can be achieved without the constexpr constraint can be achieved when algorithms are mandated to be constexpr. Without knowing that the non-constexpr functionality is not impeded by mandating constexpr implementations the algorithms won't be defined to be constexpr. The non-constexpr use of algorithms is still assumed to be the primary use of algorithms.

It may be worth having a special set of algorithms which are defined to be constexpr. I'm not aware of a correspnding proposal. I also don't see a lot if demand warranting standardization but my perception may be different from other's.

like image 39
Dietmar Kühl Avatar answered Oct 05 '22 12:10

Dietmar Kühl