C++ 11、#if 内で const を使用する方法

コンパイル時に条件がわかっている場合は、オーバーロードを使用して 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>{});
}