C++17’s Constexpr If

Cengizhan Varlı
3 min readApr 14, 2024

--

In C++17, constexpr is a keyword used to indicate that a function or object can be evaluated at compile time. It allows the result of the function or object to be used in contexts that require compile-time evaluation, such as in template arguments or array sizes.

For functions, constexpr specifies that the function is a constant expression, meaning it can be used in constant expressions. The function must be relatively simple, with a body that can be evaluated at compile time.

For objects (variables), constexpr specifies that the object is a constant expression, meaning its value is known at compile time and cannot be changed at runtime.

Constexpr If

“constexpr if” is a feature introduced in C++17 that allows you to conditionally compile code based on a compile-time condition. It's an extension of the if statement that can be used in constexpr contexts. Here’s basic structure of constexpr if;

if constexpr(cond)
statement1;
else
statement2;

Let’s try to examine and understand in detail with an example;

#include <iostream>

template <typename T>
void func(T value)
{
if constexpr (std::is_integral_v<T>)
{
std::cout << "Integer: " << value << std::endl;
}
else
{
std::cout << "Not an integer" << std::endl;
}
}

int main() {
func(5);
func("hello");
return 0;
}
Output

Let’s break down the code step by step:

  • template <typename T> void func(T value) : This declares a function template func() that takes a single argument of type T.
  • if constexpr (std::is_integral_v<T>) : This is a constexpr if statement. It checks if the type T is integral (i.e., an integer type) using std::is_integral_v<T>. The “constexpr if” statement allows for compile time branching, meaning that the code inside the block will only be compiled if the condition is true. In this case, if T is an integer type, the code inside the block will be compiled; otherwise, it will be ignored by the compiler.
  • func(5) :This calls the func() function with an integer argument 5, which will result in the "Integer: 5" message being printed.
  • func(“hello”) :This calls the func() function with a string argument “hello”, which is not an integer type. Therefore, the "Not an integer" message will be printed.

In summary, “constexpr if” is used to conditionally compile code based on a compile-time condition. Specifically, it checks if the type T passed to the func() function is an integer type using std::is_integral_v<T>. If T is an integer type, the code inside the “if constexpr” block is compiled and executed, which prints "Integer: " followed by the value of value. If T is not an integer type, the code inside the else block is compiled and executed, which prints "Not an integer".

“constexpr if” allows for more efficient code generation by avoiding unnecessary code bloat for types that don't meet the condition, as the code inside the else block is not compiled if the condition is not met. This can be particularly useful for template code where different implementations are required based on the properties of the template arguments.

--

--