Is there any reason only if constexpr
to be included in C++17?
I could do this:
template <int N>
constexpr int fib() {
if constexpr (N == 1 || N == 2) {
return 1;
} else {
return fib<N - 1>() + fib<N - 2>();
}
}
Why haven't the C++ committee considered switch constexpr
too?
template <int N>
constexpr int fib() {
switch constexpr (N) {
case 1:
case 2: return 1;
default: return fib<N - 1>() + fib<N - 2>();
}
}
It looked much cooler with switch constexpr
Or even a premature compile-time loop unwind with for constexpr
/while constexpr
without the use of template substitution/recursive template function:
constexpr void printFoo() {
for constexpr (auto i = 0; i < 10; i++) {
cout << fib<i>() << endl;
}
}
Will they be included in C++20/future versions of C++?
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.
The easiest way to check whether a function (e.g., foo ) is constexpr is to assign its return value to a constexpr as below: constexpr auto i = foo(); if the returned value is not constexpr compilation will fail.
Yes. I believe putting such const ness is always a good practice wherever you can. For example in your class if a given method is not modifying any member then you always tend to put a const keyword in the end.
A constexpr function is a function that can be invoked within a constant expression. A constexpr function must satisfy the following conditions: It is not virtual. Its return type is a literal type. Each of its parameters must be of a literal type.
Before diving into if-constexpr, it might be useful to have a quick recap of constexpr. Introduced in C++ 11, constexpr is a keyword that marks an expression or function as having a compile-time constant result. OK, so you might be wondering what the purpose of constexpr is.
constexpr functions can be used as regular functions, although internally they have greater restrictions. constexpr functions can easily be converted into regular functions as requirements change. constexpr functions compile much quicker than the equivalent template-based solutions, which scale linearly with the depth of the template-recursion.
constexpr functions compile much quicker than the equivalent template-based solutions, which scale linearly with the depth of the template-recursion. As an example, take a look at these two compile-time implementations of the Fibonacci sequence: So what is if-constexpr?
If Constexpr is a C++ 11 keyword that marks an expression or function as having a compile-time constant result. This prevents nasty side-effects sneaking into your code as it evolves.
if constexpr
was proposed relatively close to C++17 being finalized.
Embellishments (like switch
) might have deferred its inclusion.
Fancy ones like forced loop unrolling would certainly have.
It takes real work to change the C++ standard. You have to implement it yourself in a compiler as proof it can be done, convince other compiler writers it should be easy or worth the effort, work out how it should be worded in the standard to be clear and unambiguous, convince the other members of the committee that your change isn't just cruft on the language, etc.
It does not require a reason for something not to happen. Things don't happen all the time. C++ improving isn't some natural process that occurs unless someone stops it,
Tl;dr: because you didn't propose it and husband it through standardization. Get started today and it might be in C++20. "I am not worthy" of proposing is not an excuse: this is work that needs doing, not some granted boon for being awesome. One becomes awesome by doing the work. "I am lazy" is an excuse, one I am intimately familiar with.
The C++ standards committee does not, in general, add new features just because they "look cool". Each new feature is only added after a paper is submitted that proposes meticulously crafted legalese that precisely specifies the feature's syntax and semantics, which often goes through multiple revisions as all the implications are hashed out by experts.
This provides a natural barrier to adding new features: if the functionality it would add to the language is not enough to make that gruelling experience worthwhile, then nobody will bother proposing it formally.
if constexpr
is a valuable addition to the language (try rewriting the code not to use it and you'll see why) and it was not that complicated to specify: if the condition is true then the second substatement is discarded, otherwise the first substatement is discarded.
In contrast, switch constexpr
would pose much greater difficulties in wording because of the greater complexities of switch
statements. (You are welcome to try, though.) For example, you have a natural expectation of how this should work:
switch constexpr (x) {
case 1:
bar<x>();
if constexpr(y) { break; }
case 2:
baz<x>();
}
namely that if x
is 1 and y
is true then baz<x>
is not instantiated, but if x
is 1 and y
is false then baz<x>
is instantiated. If you want these semantics, you need to figure out the standardese, which will have to specify an effective procedure for determining exactly which statements to discard (keep in mind that these if
s and switch
es can be arbitrarily nested). If you don't want these semantics, your switch constexpr
is probably no more powerful than a bunch of if constexpr
's anyway but will have restrictions compared to the normal switch
statement.
These difficulties increase further with for constexpr
. Now, it might be worth it. But someone has to put in the effort.
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