if constexpr
- C++ course
- Advanced
- Lesson 3/83
- 5 min
Learn compile-time conditions with if constexpr.
if constexpr
if constexpr (C++17) is a condition evaluated at compile time. The false branch is not instantiated, so type mismatches do not error. It makes writing different code for different types in templates easy.
Example: if constexpr (std::is_integral_v<T>) return x * 2; else return x; returns twice the value for integers and the value for others. Because the false branch is not compiled, x * 2 on std::string does not error.
Use in templates
A template may be called with both integer and floating types. With if constexpr each type gets its own code; with plain if both branches would compile and meaningless code like std::string * 2 would error.
The <type_traits> header offers constants like std::is_integral_v and std::is_floating_point_v. These return true or false, which if constexpr reads at compile time.
Practice Write the twice template
Write template <typename T> auto twice(T x). With if constexpr, if std::is_integral_v<T> is true return x * 2, otherwise return x. In main call twice(5) and print the result.
Starter code
#include <iostream>
#include <type_traits>
// Write the twice template
int main() {
// Call twice(5) and print
return 0;
}Sample solution
#include <iostream>
#include <type_traits>
template <typename T>
auto twice(T x) {
if constexpr (std::is_integral_v<T>) return x * 2;
return x;
}
int main() {
std::cout << twice(5);
return 0;
}Expected output
10
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 When does if constexpr discard branches?
- At run time
- At link time
- At compile time Correct answer
- At load time
Explanation: if constexpr evaluates branches at compile time.
2 Match the branch to its purpose
| Term | Meaning |
|---|---|
if constexpr (cond) |
Compile-time branch |
if (cond) |
Run-time branch |
std::is_integral_v<T> |
Type condition |
else return x |
Default branch |
3 Complete the if constexpr line
template <typename T>
auto twice(T x) {
____ (std::is_integral_v<T>) return x * 2;
return x;
}
template <typename T>
auto twice(T x) {
if constexpr (std::is_integral_v<T>) return x * 2;
return x;
}
Explanation: if constexpr evaluates the branch at compile time.