在我的开关中,我希望案例从0变为(number_of_cases-1
),而不是自己编写数字。因此,如果我在中间删除一个案例块,则以下情况将重新编号(递减1),以便交换机再次来自(0..caseNo-1
)。
像这样(当然它不会编译,因为i++
不是已知的编译时间):
#include <iostream>
#define ALWAYS_SECOND_CASE 1
void nop(char c){}
int main()
{
int i=0;
int var=ALWAYS_SECOND_CASE;
switch(var)
{
case i++: //case 0:
nop('x');
break;
case i++: //case 1:
nop('y')
break;
case i++: //case 2:
nop('z')
break;
}
//case 1 should have been switched to, nop('y') called.
}
现在我删除了中间案例,并且没有写任何内容,最后一个案例应该从案例2更改为案例1:
#include <iostream>
#define ALWAYS_SECOND_CASE 1
void nop(char c){}
int main()
{
int i=0;
int var=ALWAYS_SECOND_CASE;
switch(var)
{
case i++: //case 0:
nop('x');
break;
case i++: //case 1: instead of case 2 like before
nop('z')
break;
}
//case 1 should have been switched to, nop('z') called,
// instead of nop('y') like before.
}
所以我不能使用变量,因为变量太多了;那么符号常量太常了,我可以做SYMC+1
,但没有SYMC++
。那么可能是枚举,还是一些不错的宏功能?
EDIT 感谢if-else提示,我只是认为,因为案例值是已知的编译时间,所以使用开关会更好..
并指定我想要做的事情:我有一个菜单char[rows][cols]={"first line","second line"}
。我想将开关案例映射到行,这样如果我想从菜单中删除一行(减少后面的行号),我将在程序的其余部分删除一个案例。
答案 0 :(得分:1)
一系列if
陈述怎么样?
int i=0;
int var=ALWAYS_SECOND_CASE;
if (var == i++) {
nop('x');
} else if (var == i++) {
nop('y');
} else if (var == i++) {
nop('z');
}
答案 1 :(得分:1)
这可能很愚蠢,但你考虑过这样的事情:
#define ALWAYS_SECOND_CASE 1
std::string some_cases = "xyz";
nop(some_cases[ALWAYS_SECOND_CASE]);
std::string some_other_cases = "xz";
nop(some_other_cases[ALWAYS_SECOND_CASE]);
我也会想起 std::map
。
答案 2 :(得分:1)
预处理器中没有状态保持结构。但是,在C ++ 11中,您可以使用lambdas来表达单个案例,将它们放在一个数组中,并在每种情况下使用类似于switch
的方式使用中断:
function<void()> cases[] = {
[] () {cout << "quick" << endl; }
, [] () {cout << "brown" << endl; }
, [] () {cout << "fox" << endl; }
};
int k = 1;
cases[k](); // <<== This is where the switch happens
现在,每次从中间移除案例时,您的数组索引都会自动“重新编号”。
答案 3 :(得分:0)
我不完全明白你想做什么,但显然你不应该使用switch
;它并不意味着你想要实现的逻辑。
您可能会改为使用一系列if(...) else if (...)
语句。
答案 4 :(得分:0)
我认为Boost Preprocessor库提供了在编译时生成switch语句所需的宏。我无法访问编译器权限以检查下面的代码,但如果它不编译它应该非常接近将解决您的问题。
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/repetition/for.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/comparison/not_equal.hpp>
#define OPS (x, y, z)
#define NOPS BOOST_PP_TUPLE_SIZE(OPS)
#define PRED(r, state) BOOST_PP_NOT_EQUAL( \
BOOST_PP_TUPLE_ELEM(2, 0, state) \
, BOOST_PP_TUPLE_ELEM(2, 1, state) \
)
#define OP(r, state) ( \
BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)) \
, BOOST_PP_TUPLE_ELEM(2, 1, state) \
)
#define MACRO(r, state) \
case BOOST_PP_TUPLE_ELEM(2, 0, state): \
BOOST_PP_TUPLE_ELEM(NOPS, BOOST_PP_TUPLE_ELEM(2, 0, state), OPS)(); \
break;
void x() { }
void y() { }
void z() { }
main() {
int i = 0;
switch(i) {
BOOST_PP_FOR((0, NOPS), PRED, OP, MACRO)
}
}
每当您想要添加或删除操作时,只需修改OPS的定义,并且案例值应自动重新编号。我知道有些人不喜欢使用预处理器,但它可以做的一些事情非常棒。
更新:我再次访问了编译,并且我验证了上面的代码与广告一样有效。但是,它需要Boost 1.49,并且必须在编译行中包含-DBOOST_PP_VARIADICS。