C++のswitch文を書いていて、「文字列や小数で分岐できないの?」「なぜコンパイルエラーになるの?」と困ったことはありませんか?
実は、switch文は「何でも条件に使える」わけではなく、整数型として扱える値だけという厳しい制限があります。
この記事を読み終えると、あなたはswitch文の制限と、それぞれのケースでの対処法を完全に理解できると思いますので、ぜひ最後まで読んでいただけると嬉しいです。
switch文に使える値のルール
switch文の条件式に使えるのは、基本的に以下の3つだけです。
- ✅ 整数型(int / char / short / long など)
- ✅ enum(列挙型)
- ✅ constexpr な値(コンパイル時定数)
逆に言うと、これ以外はすべて使えません。
それでは、具体的に「使えないケース」を見ていきましょう。
使えないケース① double / float は使えない
小数型(浮動小数点数)はswitch文で使えません。
▼main.cpp
#include <iostream>
int main() {
double x = 1.5;
// ❌ コンパイルエラー
// switch (x) {
// case 1.5:
// std::cout << "1.5です\n";
// break;
// }
return 0;
}エラーメッセージ(例)
error: switch quantity not an integer
なぜ使えないのか?
switch文は内部的にジャンプテーブルという高速分岐を使うため、値が離散的(飛び飛び)である必要があります。
浮動小数点数は連続的で、誤差もあるため、switch文の仕組みでは扱えません。
対処法:if文を使う
▼main.cpp
#include <iostream>
int main() {
double x = 1.5;
// ✅ if文を使う
if (x == 1.5) {
std::cout << "1.5です\n";
} else if (x == 2.5) {
std::cout << "2.5です\n";
} else {
std::cout << "その他\n";
}
return 0;
}実行結果
1.5です
使えないケース② std::string は使えない
文字列(std::string)もswitch文で使えません。
▼main.cpp
#include <iostream>
#include <string>
int main() {
std::string cmd = "start";
// ❌ コンパイルエラー
// switch (cmd) {
// case "start":
// std::cout << "ゲーム開始\n";
// break;
// }
return 0;
}エラーメッセージ(例)
error: switch quantity not an integer
なぜ使えないのか?
switch文は文字列比較の仕組みを持たないため、std::stringは扱えません。
対処法:if-else や map を使う
▼main.cpp(if-else版)
#include <iostream>
#include <string>
int main() {
std::string cmd = "start";
// ✅ if-else を使う
if (cmd == "start") {
std::cout << "ゲーム開始\n";
} else if (cmd == "load") {
std::cout << "ロード\n";
} else if (cmd == "exit") {
std::cout << "終了\n";
} else {
std::cout << "無効なコマンド\n";
}
return 0;
}実行結果
ゲーム開始
▼main.cpp(map版 – より高速)
#include <iostream>
#include <string>
#include <unordered_map>
int main() {
std::string cmd = "start";
// ✅ mapで疑似switch
std::unordered_map<std::string, int> cmdMap = {
{"start", 1},
{"load", 2},
{"exit", 3}
};
switch (cmdMap[cmd]) {
case 1:
std::cout << "ゲーム開始\n";
break;
case 2:
std::cout << "ロード\n";
break;
case 3:
std::cout << "終了\n";
break;
default:
std::cout << "無効なコマンド\n";
}
return 0;
}実行結果
ゲーム開始
使えないケース③ 実行時に決まる値は case に書けない
これも初心者が超混乱するポイントです。
▼main.cpp
#include <iostream>
int main() {
int a = 10;
int b = 20;
// ❌ コンパイルエラー
// switch (a) {
// case b: // 変数bは使えない
// std::cout << "bと一致\n";
// break;
// }
return 0;
}エラーメッセージ(例)
error: case label does not reduce to an integer constant
なぜ使えないのか?
caseに書ける値はコンパイル時定数のみです。実行時に決まる変数は使えません。
対処法:定数や enum を使う
▼main.cpp
#include <iostream>
int main() {
int a = 10;
const int b = 10; // ✅ constなら使える
switch (a) {
case b:
std::cout << "bと一致\n";
break;
case 20:
std::cout << "20\n";
break;
}
return 0;
}実行結果
bと一致
使えないケース④ 範囲指定はできない
「スコアが80~100点なら優」のような範囲指定はswitch文でできません。
▼main.cpp
#include <iostream>
int main() {
int score = 85;
// ❌ C++標準では不可(GCC拡張では可能だが非推奨)
// switch (score) {
// case 80 ... 100:
// std::cout << "優\n";
// break;
// }
return 0;
}なぜ使えないのか?
C++標準では範囲指定の構文が未対応です。(GCCコンパイラの拡張機能としては存在しますが、移植性がありません)
対処法:if文を使う
▼main.cpp
#include <iostream>
int main() {
int score = 85;
// ✅ if文で範囲指定
if (score >= 80 && score <= 100) {
std::cout << "優\n";
} else if (score >= 60) {
std::cout << "良\n";
} else {
std::cout << "不可\n";
}
return 0;
}実行結果
優
使えないケース⑤ bool は実質使えない
bool型はswitch文で書けなくはないですが、意味が薄いです。
▼main.cpp
#include <iostream>
int main() {
bool flag = true;
// 書けるけど...
switch (flag) {
case true:
std::cout << "真\n";
break;
case false:
std::cout << "偽\n";
break;
}
return 0;
}実行結果
真
対処法:普通に if で良い
▼main.cpp
#include <iostream>
int main() {
bool flag = true;
// ✅ if の方が自然
if (flag) {
std::cout << "真\n";
} else {
std::cout << "偽\n";
}
return 0;
}実行結果
真
boolはtrue/falseの2値しかないため、switchを使う意味がありません。
【重要】私が実際にswitch文で困った体験談
体験談1: コマンドを文字列で分岐しようとしてエラー
自主制作で「テキストベースのRPG」を作っていた時のことです。プレイヤーの入力コマンドで分岐する処理を以下のように書きました。
std::string command;
std::cin >> command;
switch (command) { // ❌ エラー!
case "attack":
std::cout << "攻撃!\n";
break;
case "defend":
std::cout << "防御!\n";
break;
}コンパイルすると、「switch quantity not an integer」というエラーが出ました。
原因を調べたところ、switch文は文字列が使えないことを初めて知りました。結局、if-elseで書き直しました。
// ✅ if-else で解決
if (command == "attack") {
std::cout << "攻撃!\n";
} else if (command == "defend") {
std::cout << "防御!\n";
}体験談2: スコア判定で範囲指定しようとしてエラー
自主制作でクイズゲームを作っていた時、スコアの範囲で成績を判定する処理を以下のように書きました。
int score = 85;
switch (score) {
case 80 ... 100: // ❌ エラー!
std::cout << "優\n";
break;
case 60 ... 79:
std::cout << "良\n";
break;
}GCCでは動いたのですが、Visual Studioでビルドするとエラーになりました。
原因は、範囲指定がC++標準ではなく、GCC拡張機能だったこと。if文に書き直したら、どの環境でも動くようになりました。
// ✅ if文で解決
if (score >= 80) {
std::cout << "優\n";
} else if (score >= 60) {
std::cout << "良\n";
}よくある失敗例と対処法
失敗例1: 変数をcaseに書いてエラー
症状: case label does not reduce to an integer constant
原因: caseには定数しか書けない
対処法: constやenum、リテラル値を使う
// NG
int max = 100;
switch (score) {
case max: // 変数は使えない
break;
}
// OK
const int MAX = 100;
switch (score) {
case MAX: // 定数なら使える
break;
}失敗例2: charポインタ(C文字列)で分岐しようとした
症状: switch quantity not an integer
原因: C文字列(char*)は文字列ではなくポインタ
対処法: if文でstrcmpを使うか、std::stringでif-else
// NG
const char* cmd = "start";
switch (cmd) { // ポインタは使えない
case "start":
break;
}
// OK(strcmp使用)
#include <cstring>
if (strcmp(cmd, "start") == 0) {
// ...
}失敗例3: 小数を整数に丸めて使おうとした
症状: 思った通りに分岐しない
原因: 丸め誤差や変換ミス
対処法: 最初からif文で小数比較する
// NG(誤差が出る可能性)
double x = 1.5;
switch ((int)x) { // 1になる
case 1:
break;
}
// OK
if (x == 1.5) {
// ...
}switch文を使うべき場面
switch文が向いているのは以下のような場面です。
- ✅ 状態管理(ゲームのシーン遷移など)
- ✅ メニュー処理(1=新規、2=ロード、3=終了)
- ✅ enum 分岐(列挙型による分岐)
- ✅ 固定値分岐(整数の一致判定)
▼良い例(enum使用)
#include <iostream>
enum State { TITLE, PLAY, RESULT };
int main() {
State state = PLAY;
switch (state) {
case TITLE:
std::cout << "タイトル画面\n";
break;
case PLAY:
std::cout << "ゲーム中\n";
break;
case RESULT:
std::cout << "リザルト\n";
break;
}
return 0;
}実行結果
ゲーム中
switch vs if 比較表
| 比較項目 | switch | if |
|---|---|---|
| 整数型 | ○ | ○ |
| 小数型 | × | ○ |
| 文字列 | × | ○ |
| 範囲指定 | × | ○ |
| 複雑な条件 | × | ○ |
| 見やすさ(分岐多) | ○ | △ |
| 速度(分岐多) | ○ | △ |
まとめ
switch文の制限をまとめます。
- ✅ 使えるのは整数型・enum・定数のみ
- ✅ double/floatは使えない → if文を使う
- ✅ std::stringは使えない → if-else か map+switch
- ✅ 変数はcaseに書けない → 定数のみ
- ✅ 範囲指定は不可 → if文を使う
- ✅ boolは実質不要 → 普通にifでOK
- ✅ 向いているのは状態管理・enum・固定値分岐
これでswitch文の制限と対処法はバッチリですね!
使えない場面では無理せずif文を使うのが正解です。
ここまで読んでくださり、ありがとうございました。
この記事が皆様の学習に役立てば幸いです。

