Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If there's a constexpr if statement, why not other constexpr statements too? [closed]

Tags:

c++

c++17

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++?

like image 294
Steve Fan Avatar asked Aug 16 '17 05:08

Steve Fan


People also ask

Which is false about constexpr?

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.

How do I know if a function is constexpr?

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.

Should I use constexpr everywhere?

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.

What is a constexpr function?

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.

What is if-constexpr and how do I use it?

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.

What is the difference between constexpr and regular functions?

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.

What is the difference between if-constexpr and template-based solutions?

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?

What is constexpr in C++?

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.


2 Answers

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.

like image 87
Yakk - Adam Nevraumont Avatar answered Oct 10 '22 00:10

Yakk - Adam Nevraumont


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 ifs and switches 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.

like image 26
Brian Bi Avatar answered Oct 10 '22 01:10

Brian Bi