Why is `std::invoke` not constexpr? - c++

Shouldn't std::invoke be constexpr especially after constexpr lambdas in C++17?
Are there any obstacles that will prevent this?

Update: P1065 will make it constexpr.
Keep original post for historical reason:
From the proposal:
Although there is possibility to implement standard conforming invoke function template as a constexpr function, the proposed wording does not require such implementation. The main reason is to left it consistent with existing standard function objects, that could have such definition, like std::mem_fn, std::reference_wrapper and operator wrappers. Furthermore imposing such requirement will block the implementation of invoke that refers to std::mem_fn.
This proposal assumes that constexpr addition to the header would be applied consistently by a separate proposal.
Both constexpr and standard library based implementation are presented in Implementability section of the proposal.
Related CWG issue #1581: When are constexpr member functions defined?.

Related

What is the use of a constexpr function in C++23?

The keyword constexpr enforced pretty tight restrictions on functions on its introduction into the C++11 standard. These restrictions were loosened with C++14 and C++20 (most noteworthy):
C++14 allowed multiple return statements, static_asserts etc.
C++20 allowed try and asm
C++23 further softens these restrictions. From what I can see in cppreference, constexpr for functions seems to only have the following meaning left:
it must not be a coroutine
for constructor and destructor, the class must have no virtual base classes
For constexpr function templates and constexpr member functions of class templates, at least one specialization must satisfy the abovementioned requirements.
C++23 even removed the restriction that a constexpr function must be "evaluatable" at compile time for any type in p2448r2. From my understanding this completely removed the idea of a constexpr function to be evaluated at compile time.
Is that it? If so, how is a constexpr function even useful anymore?
What you actually seem to ask is: why not make anything constexpr by default?
Because you might want others to not use a function at compile-time, to give you a possibility to switch to a non-constexpr implementation later.
Imagine this:
You see a library function, which you'd like to use at compile-time.
Let's say, size_t RequiredBufferSize();. If it happens to be constexpr, you can allocate the buffer on the stack, or something like that.
You're not sure if it's supposed to work at compile-time, because there's no constexpr in our imaginary language.
You try it, and it does work at compile-time. You start using it this way.
Let's say the implementation was {return 42;}, which is constexpr.
A new version of the library is released, the function no longer works at compile-time (e.g. the size is loaded from a config file).
You complain to the developer, and he argues that the function was never intended to work at compile-time, and you relied on an implementation detail.

Is there anything else to std::cbegin() other than begin()ing a const reference?

I'm constrained to writing C++11 code, but I want to use std::cbegin(). So, I'm looking at GCC 5.4.0's implementation, in /usr/include/c++/5/bits/range_access.h on my system, thinking I might write something similar, and I see:
template<class _Container>
inline constexpr auto
cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
-> decltype(std::begin(__cont))
{ return std::begin(__cont); }
is that all there is to it? Am I missing something? If that's it, how come it wasn't part of C++11 like std::begin()?
is that all there is to it?
Yes.
Am I missing something?
Not that I'm aware of.
If that's it, how come it wasn't part of C++11 like std::begin()?
The global templates seem to have been part of the original proposal as an alternative to the member functions, but the proposal preferred to only provide the member functions in favour of providing either just the global templates, or both the templates and members. (Assuming this is the original proposal: N1674).
The committee chose to include the member function alternative in C++11, and the template not until C++14. I'm not part of the committee, and cannot speak for them, but my guess is that the attitude of the proposal may have affected the decision:
While this generic adapter alternative seems quite straightforward, we nonetheless favor the
member function approach as proposed above. It seems more in keeping with current C++
programming idioms, such as the parallel use of
rbegin
as a container member function rather
than as a generic adapter
Here is the development for the C++ Standard Library Defect Report issue (2128) where the template versions were decided to be adopted into C++14 after all.
No, that covers it.
Although a small function can be added to the standard with a relatively small amount of effort, time is finite and the committee doesn't have unlimited resource. Another example of a reasonably useful and trivial function that was omitted until C++14 is std::make_unique. Things improve over time.

C++14 How often should I use constexpr?

I've been reading a book about C++14/11. I just finished reading a chapter about the constexpr keyword. I know what it's used for, but how often should I use constexpr? Should I use it even in code for classes I know will never be used to create contstexpr objects? (Just in case, because it doesn't cost me anything, right?)
C++14 How often should I use constexpr?
There's an extensive discussion in item 15 (Use constexpr whenever possible) of the Scott Meyer's book Effective Modern C++.
The outline of this item is that constexpr should be used whenever possible, due to the fact that constexpr functions and objects can be used in a wider range of contexts than the non-constexpr ones.
However, in the same item the author mentions a caveat of overusing constexpr. That is, if you decide to qualify an object or a function as constexpr your clients will be allowed to use it in constexpr contents. However, if you later decide that this code must not be constexpr and remove constexpr, this can cause your code not to compile including the side effects that this will have to your clients.
Quoting from original text:
“Use constexpr whenever possible” is your willingness to make a long-term commitment to the constraints it imposes on the objects and
functions you apply it to.

Why is std::tie not marked constexpr for C++14?

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!
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.

Which parts of the C++14 Standard Library could be and which parts will be made constexpr?

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?
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)
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.