With the new relaxed C++14 constexpr rules, compile-time programming becomes a lot more expressive. I wonder whether the Standard Library will also be upgraded to take advantage. In particular, std::initializer_list
, std::pair
, std::tuple
, std::complex
, std::bitset
and std::array
seem like prime candidates to be marked constexpr
wholesale.
Questions:
constexpr
? constexpr
? <cmath>
and <algorithm>
marked constexpr
? The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.
A constexpr (or indeed, any kind of variable) need not be stored anywhere if its address is never taken. A constexpr in global or namespace ,when I address it,it should store in .
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.
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.
which parts of the Standard Library will now be marked constexpr?
From the draft that I've looked at for C++14, N3690, the following will be changed to constexpr
thus far (In comparison with the C++11 standard)†:
std::error_category
's default constructorstd::forward
std::move
std::move_if_noexcept
std::pair
's operator comparisonsstd::get
for std::pair
and std::tuple
.std::make_tuple
std::tuple
's operator comparisonsstd::optional
's operator comparisonsstd::optional
's constructors (save for move)operator[]
and size
for std::bitset
and other containers.std::complex
's operator comparisons† Since I did this manually, you can expect some errors :(
For another possibly more correct list of constexpr
additions you can check: N3469, N3470, and N3471
which other parts could be marked constexpr?
Most of the stuff that could be constexpr
(std::numeric_limits
evaluation, std::tuple
and std::pair
constructors, etc) were already marked as constexpr
in the C++11 standard. There was a bug in which std::ratio
's time points and other components weren't marked as constexpr
but it was fixed in N3469.
Something that would benefit from constexpr
additions would be std::initializer_list
, which didn't get any this time around (and I'm unsure if there have been any proposals to allow it).
are there backwards compatibility reasons not to do so?
Since this is an extension, most stuff won't be broken since older code will still compile as-is and nothing is now ill-formed. However adding constexpr
to older things that didn't have it could lead to some surprising results if you didn't expect it, such as the example provided here (Thanks TemplateRex)
Last week (Sep 23-28, 2013) the standards committee added constexpr
to more routines in the standard library.
operator ()
method of all the comparison / logical / bitwise named operators. (less
, greater
, plus
, minus
, bitwise_and
, logical_or
, not1
- and the rest)@TemplateRex: We're getting closer to sorting arrays at compile time.
However, we also resolved LWG issue 2013, stating that standard library implementers do NOT have the freedom to make calls that are not defined in the standard as constexpr
as constexpr
, since that kind of difference between implementations could change the behavior of some code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With