mfontanini が説明しているように (そしてコンパイラが文句を言っています)、非型のテンプレート パラメータはコンパイル時の定数でなければなりません。そして、「const int p = i;」でだます試み 役に立ちません。p は定数変数かもしれませんが、コンパイル時の定数ではありません。C++11 コンパイラは、ここで何が問題なのかをより適切に伝えることができますが、問題を回避するのには役立ちません。実際、この問題を直接回避する方法はありません。
user315052 が示唆するように、最も簡単な解決策は明示的な切り替えです。そして、これを 1 回だけ実行し、1 対 2 のスイッチを入れるだけであれば、それ以上の労力を費やす価値はありません。
もちろん、スイッチを何度も実行している場合は、関数でラップするのは簡単です。
void bar(int i) {
switch(i) {
case 1: foo(userInput<1>::typeName()); return;
case 2: foo(userInput<2>::typeName()); return;
default: throw someException;
}
しかし、2 つ以上のケースがある場合、または一連の値が常に流動的である場合は、Boost.Preprocessor を使用してクラフトを自動化する必要があります。これは次のようになります。
#define FOO_CASES_ 50
#define FOO_PASTE_(rep, i, _) case i: foo(userInput< i >::typeName()); return;
void bar(int i) {
switch (i) {
BOOST_PP_REPEAT(FOO_CASES_, FOO_PASTE_, _)
default: throw someException;
}
}
#undef FOO_CASES_
#undef FOO_PASTE_
または、代わりに、コンパイルする .cpp ファイルを作成するコード ジェネレーターを記述します。
#!/usr/bin/env python
with file('bar.cpp', 'w') as f:
f.write('void bar(int i) {\n')
f.write(' switch(i) {\n')
for i in range(50):
f.write(' case %d: foo(userInput<%d>::typeName()); return;\n' % (i, i))
f.write(' default: throw someException;\n')
f.write(' }\n')
f.write('}\n')
さらに別の方法は、適切なオブジェクト/関数などで初期化されたルックアップ配列 (またはベクトル) を作成することです。したがって、userInput の代わりに *userInputLookup[i] を使用できます。しかし、正確な使用例や、C++11 を使用しているかどうかを知らなければ、詳細を説明することは困難です。