25

This is a follow-up question to my previous questions "Which parts of the C++14 Standard Library could be and which parts will be made constexpr?" and "Guidelines to do constexpr operator-overloading?"

In the runtime world, a nice idiom to overload operator< for a struct of several data members, is to use std::tie to convert a struct into a std::tuple and piggy-back on its operator< which does the Right Thing™ (lexicographic comparison on the various members).

In C++14, many parts of std::tuple are made constexpr, in particular make_tuple, std::get and the earlier mentioned operator<. However, it appears that the seemingly related std::tie is not marked constexpr. This is rather annoying because it makes defining user-defined literal types that can be compared at compile-time more verbose than necessary.

Question: are there any technical reasons for which std::tie is not marked constexpr for C++14?

UPDATE: LWG issue 2301, implemented in libc++ and libstdc++ bug 65978

UPDATE2: fixed by @JonathanWakely a little over 3 hours after submitting the libstdc++ bug report!

user2672165
  • 2,986
  • 19
  • 27
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • 2
    Since it only creates a tuple of references, there can really be no reason not to mark it `constexpr`. – Xeo Sep 10 '13 at 20:17
  • @Xeo I wish everything was constexpr by default, and the compiler would just give a warning whenever it can't evaluate – TemplateRex Sep 10 '13 at 20:22

1 Answers1

5

In any case where it would utilize constexprness, make_tuple should behave exactly the same as tie except that notionally tie would add an extra level of unneeded indirection from the references. Thus there's no need for tie to be constexpr since make_tuple would serve that purpose.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • `make_tuple` is indeed a workaround at compile-time, but now whenever I drop down to the runtime world, wouldn't `operator<` be making 2 extra copies? And since functions don't overload on constexpr, having 2 overloads is no option either. – TemplateRex Sep 10 '13 at 20:39
  • FWIW, you can `std::make_tuple(std::cref(args)...)` the whole thing, but eeeeh. – Xeo Sep 10 '13 at 20:46
  • @TemplateRex Once you drop down to runtime you're no longer in `constexpr` land so you use `tie` instead (unless I miss something here). – Mark B Sep 10 '13 at 20:51
  • but the whole point of the relaxed C++14-style `constexpr` is to *gracefully* drop to runtime land, not to incur needless copies. This was the main pain point in C++11, that needlessly forced you into recursion and `?` operator style coding. Now we have `for`, `switch` and `if`, and can write algorithms (if only lambdas were `constexpr`). – TemplateRex Sep 10 '13 at 20:53
  • @Xeo Eeeh indeed. I think I'll try a simple definition `private::tie` to do what you are proposing, or simply copy-paste the `std::tie`, rename it and mark it `constexpr`. – TemplateRex Sep 10 '13 at 20:57
  • 3
    @MarkB, you don't want to have to implement a type's `operator<` twice, one way when using it in a (possibly) constant expression context and another way (with a different name) to use elsewhere, that's just annoying. – Jonathan Wakely Sep 10 '13 at 23:00
  • @JonathanWakely will this get fixed or should I submit a DR? – TemplateRex Sep 11 '13 at 09:28
  • @TemplateRex, I don't know of any existing DR or national body comment, so please submit one – Jonathan Wakely Sep 11 '13 at 12:21
  • @JonathanWakely could you point me to the appropriate channels, please? – TemplateRex Sep 11 '13 at 13:16
  • @JonathanWakely thanks, I have submitted a DR, almost identical in substance as Issue 2275 where the same point was observed about `forward_as_tuple`. – TemplateRex Sep 11 '13 at 15:18