std::algorithm
algorithms act on iterators. There is a technical reason why making them constexpr
would usually either prevent compiling them (in C++11) or do nothing (in C++14 or with conditional-constexpr
), but there's also a semantic reason why it wouldn't make sense for them to be constexpr
.
The technical reason is that constexpr
functions cannot call non-constexpr
expressions. ForEveR points out that template constexpr
functions can't be evaluated at compile-time if they call non-constexpr
expressions.
In the case of std::algorithm
, evaluating constexpr
functions in std::algorithm
would require the functions for accessing container iterators to be constexpr
, which in turn would require the iterators themselves to be constexpr
types. But this is impossible almost by definition; containers are typically designed as lightweight access to heap-allocated memory, but heap memory cannot be allocated at compile time (of course). In the comments below, dyp points out that iterators don't always point to containers, but even these iterators are unlikely to be useable at compile-time; for instance, streams objects are of course not readable or writeable at compile time, since IO cannot be done at compile time.
This leads to the semantic problem: constexpr
semantically means that a function is intended to be possible to evaluate at compile time. Declaring functions conditionally-constexpr
when it is impossible to evaluate them at compile time would make the API confusing and misleading.
Now, I think the language would be improved if there were a way to create and use containers at compile time; this would make constexpr
that much more similar to Lisp's macro capabilities. This may eventually be added, but currently it's not really supported by existing standard library code. The most flexible approach, of allowing some objects to live on the heap during compile time, is, as mentioned above, not supported at all by the core language, and it would create some serious complications. For instance, what would it be legal to do with such objects? Either their lifetimes would need to be limited to compile-time only, or they would need to be included as static const memory in the final program (like a string literal), or...what?