コンパイル時に条件がわかっている場合は、オーバーロードを使用して if constexpr
を模倣できます 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>{});
LoPiTaLとして コメントに記載されていますが、これは if constexpr
と完全に同等ではありません 、両方の foo
のため コンパイルする必要があります。このテクニックは、テンプレートを扱うときに重要になります。プレーンな if
で 両方のブランチは、同じテンプレート パラメーターのセットでコンパイルされます。オーバーロードにより、ブランチを効果的に破棄できます。
たとえば、次のコードは失敗します:
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);
}
C++17 では 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);
}
C++11 での回避策はオーバーロードです:
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>{});
}