C++ 11, how to use a const inside an #if
If the condition is known at compile-time, you can use overloading to mimic if constexpr
in C++11:
void foo(std::true_type) { // if (xIsZero)
}
void foo(std::false_type) { // if (!xIsZero)
}
constexpr bool xIsZero = ...;
foo(std::integral_constant<bool, xIsZero>{});
As LoPiTaL noted in comments, this is not fully equivalent to if constexpr
, because both foo
s have to compile. This technique becomes important when we work with templates. With plain if
both branches are compiled with the same set of template parameters. With overloading we can effectively discard branches.
For example, this code fails:
template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
if (i > 0) {
consume_positive_i(i);
foo(std::integral_constant<unsigned int, i - 1>{});
} else
consume_zero_i(i);
}
In C++17 it can easily be fixed with if constexpr
:
template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
if constexpr (i > 0) {
consume_positive_i(i);
foo(std::integral_constant<unsigned int, i - 1>{});
} else
consume_zero_i(i);
}
The workaround in C++11 is overloading:
void foo(std::integral_constant<unsigned int, 0>) {
consume_zero_i(i);
}
template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
consume_positive_i(i);
foo(std::integral_constant<unsigned int, i - 1>{});
}