0

I have read about constexpr in C++17 using this reference link.

Then, I made C++ program to test constexpr :

#include <iostream> int i = 10; int func() { if constexpr (i == 0) return 0; else if (i > 0) return i; else return -1; } int main() { int ret = func(); std::cout<<"Ret : "<<ret<<std::endl; } 

But, compiler give an error:

main.cpp: In function 'int func()': main.cpp:8:25: error: the value of 'i' is not usable in a constant expression if constexpr (i == 0) ^ main.cpp:4:5: note: 'int i' is not const int i = 10; 

Why gives an error?

2
  • 9
    Probably because b i is not a compile-time constant (as noted in the error message!). Commented Sep 12, 2017 at 11:07
  • 7
    Because "the value of 'i' is not usable in a constant expression". What's unclear about that? Commented Sep 12, 2017 at 11:08

2 Answers 2

7

You misunderstood the meaning of if constexpr. This is not a test for const expression to be performed at runtime, it is a test of a logical expression to be performed at compile time.

The construct is roughly similar to #if of preprocessor, in that the other branch is eliminated, along with code that may otherwise not compile.

This will work:

template<int i> int func() { if constexpr (i == 0) return 0; else if constexpr (i > 0) return i; else return -1; } 

The compiler knows the value of i at compile time, so depending on its value only one of the three branches is going to remain in the compiled code.

Sign up to request clarification or add additional context in comments.

3 Comments

isnt is up to the compiler to decide if it is evaluated at runtime or compile time? If yes, then it cannot eliminate the other branches. What I actually want to know: is it really ok to write something like int foo() { if constexpr (1==0) { return "this is the wrong type"; } else { return 0;} } ?
@tobi303 This is the whole point of if constexpr that the remaining branch must be eliminated at compile time. Your code should absolutely compile. Moreover, you can use auto for the return type, and decide on the const condition which type you are going to return. According to specification, this should work.
@tobi303 Part of the reason to have this is so we can actually write code like if constexpr (std::is_same_v<int, T>) and it actually works instead of having to use SFINAE. See this example: coliru.stacked-crooked.com/a/4fd12ae025b3ac0c
5

if constexpr ( condition ) works compile time, so condition must be evaluable compile time.

int i = 0 isn't a constant variable, so i == 0 isn't evaluable compile time.

Try with int const i = 0 or, better, constexpr int i = 0.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.