Wiki で次のステートメントが見つかりました:
C++ 11では、constexprで宣言された関数の概念が導入されました。コンパイル時に実行できる関数。それらの戻り値は、整数テンプレート引数などの定数式を必要とする操作によって消費される可能性があります。ただし、C++ 11 constexpr関数には、返される単一の式(static_assertsおよびその他の少数の宣言)しか含めることができませんでした。
C++ 14は、これらの制限を緩和します。 Constexprで宣言された関数に次のものが含まれるようになりました。条件付き
- .。
- 分岐ステートメント
if
およびswitch
それで、c ++ 14/c ++ 17のconstexpr関数にスイッチを入れることは実際に可能ですか?そして、可能であれば、そのための構文は何ですか?たとえば、次のようなものが必要です。
enum class Terrain : std::uintmax_t {
ROAD,
SOIL,
GRASS,
MUD,
SNOW,
};
constexpr float
getStepPrice(Terrain const& terrain)
{
switch constexpr (terrain)
{
case Terrain::ROAD: return 1.0f;
...
}
}
それで、c ++ 14/c ++ 17のconstexpr関数にスイッチを入れることは実際に可能ですか?
はい。
そして、可能であれば、そのための構文は何ですか?
構文について特別なことはまったくありません。通常のswitch
です。このような:
constexpr int fun (int i) {
switch(i) {
case 0: return 7;
default: return 5;
}
}
int main () {
int arr[fun(3)];
}
ではない正確に。 if constexpr
の場合、結果のコードに分岐がないので安心できます。さらに、破棄されたステートメントはコンパイルする必要はありません。これらは、真のswitch constexpr
に期待できる保証です。
class Dog;
class Snake;
#define USE_IF
template<typename Pet>
constexpr void foo(Pet pet) {
#ifdef USE_IF
// This works
if constexpr(std::is_same_v<Pet, Dog>) pet.bark();
else pet.slither();
#else
// This doesn't
switch (std::is_same_v<Pet, Dog>) {
case true: pet.bark(); break; // <== Error if Snake
case false: pet.slither(); break; // <== Error if Dog
}
#else
}
ところで、私は、実用的な目的のために、バウムの受け入れられた答えに対して少し気まぐれです。優れたコンパイラーは、constexpr関数、さらにはconstexpr以外のインライン関数を使用して、switch-caseステートメントから論理的に不可能なビットを排除できると思います。