正如 mfontanini 解释的(并且您的编译器抱怨),非类型模板参数必须是编译时常量。而你试图用“const int p = i;”来愚弄它 没有帮助;p 可能是常量变量,但它不是编译时常量。C++11 编译器可以更好地告诉您这里出了什么问题,但它不能帮助您解决问题。事实上,没有直接的方法可以解决这个问题。
正如 user315052 所建议的那样,最简单的解决方案是显式切换。而且,如果您只这样做一次,并且只是打开 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')
另一种选择是创建一个查找数组(或向量),该数组使用适当的对象/函数/任何内容进行初始化,因此您可以使用 *userInputLookup[i] 代替 userInput。但是在不知道确切的用例以及是否使用 C++11 的情况下,很难提供详细信息。