32

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:

  • which parts of the Standard Library will now be marked constexpr?
  • which other parts could be marked constexpr?
  • e.g. why aren't the functions from <cmath> and <algorithm> marked constexpr?
  • are there backwards compatibility reasons not to do so?
TemplateRex
  • 69,038
  • 19
  • 164
  • 304

2 Answers2

26

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 constructor
  • std::forward
  • std::move
  • std::move_if_noexcept
  • All of std::pair's operator comparisons
  • std::get for std::pair and std::tuple.
  • std::make_tuple
  • All of std::tuple's operator comparisons
  • All of std::optional's operator comparisons
  • All of std::optional's constructors (save for move)
  • operator[] and size for std::bitset and other containers.
  • All of 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)

Rapptz
  • 20,807
  • 5
  • 72
  • 86
  • +1 thanks, very nice overview. I wonder though why a) `std::array` is not completely `constexpr`, and b) why the modifying member functions (`operator*=` etc.) of e.g. `std::complex` are not marked `constexpr`. As is shown in [this Q&A](http://stackoverflow.com/q/17744842/819272), such behavior is already implemented by Clang. Similarly, what are the obstacles to making the entire `` and `` headers `constexpr`? I would like to be able to e.g. sort arrays in compile-time. – TemplateRex Aug 05 '13 at 09:26
  • Let us also note that the rules for what can be in a `constexpr` are fairly relaxed. Checking the test cases of Clang I noted things like a `for` loop for example. – Matthieu M. Aug 05 '13 at 09:35
  • @MatthieuM. Yes, very relaxed, so I think the current N3690 draft is rather restrictive compared to what *could* be done. Ideally, I'd really like e.g. `std::complex` and the other value classes to be made entirely `constexpr`. – TemplateRex Aug 05 '13 at 09:38
  • BTW, there could be a backwards compatibility problem, see e.g. [this thread on the Clang mailinglist](http://clang-developers.42468.n3.nabble.com/libcxx-RFC-C-14-and-beyond-td4031862.html) – TemplateRex Aug 05 '13 at 19:44
  • @TemplateRex Adding things to be `constexpr` could cause breaking changes, you're possibly right. – Rapptz Aug 05 '13 at 19:49
4

Last week (Sep 23-28, 2013) the standards committee added constexpr to more routines in the standard library.

  • forward_as_tuple
  • the 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.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45
  • +1 tnx for the update! what about `std::reverse_iterator` (about which there is a DR)? And I also submitted (past the dealdline, sorry) a DR about `std::tie`, similar to `std::forward_tuple`. Is there any chance those will get `constexpr` before C++14 is set in stone? – TemplateRex Oct 01 '13 at 19:35
  • BTW, could you give an (however subjective) impression about the Committee support for even more liberal `constexpr` in C++17? E.g. the NB comment on `constexpr` lambda sounds really promising. And I coded up my own implementation of `std::bitset` that -apart from IO and string conversion- is `constexpr` wholesale. And I think the library is leaving some more opportunities behind were the language would allow it. Can you comment on why those were not proposed? And would a C++17 proposal for such broad-based library extensions be received favorably? – TemplateRex Oct 01 '13 at 19:59
  • I can't say why additional bits were not proposed; there were simply no papers proposing additions. The function objects and forward_as_tuple were added because I wrote a paper and issue and presented them. – Marshall Clow Oct 01 '13 at 20:05
  • 1
    Do I think the library has more opportunities for constexpr? Yes. – Marshall Clow Oct 01 '13 at 20:06