1

在我的开关中,我希望案例从 0 变为 ( number_of_cases-1),而无需自己编写数字。这样如果我在中间删除一个 case 块,以下 case 会重新编号(减 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++。那么也许是枚举,或者一些不错的宏函数?

编辑感谢 if-else 提示,我只是认为由于 case 值在编译时是已知的,因此使用 switch 会更好。

并指定我想要做什么:我有一个菜单char[rows][cols]={"first line","second line"}。我想将 switch case 映射到行,这样如果我想从菜单中删除一行(减少行号之后的行),我将只删除程序其余部分中的一个 case。

4

5 回答 5

2

预处理器中没有状态保持结构。但是,在 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

现在,每次从中间删除一个案例时,您的数组索引都会自动“重新编号”。

于 2012-05-26T11:42:14.060 回答
1

This is perhaps silly, but have you considered something like:

#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 comes to mind, too.

于 2012-05-26T11:27:58.007 回答
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');
 }
于 2012-05-26T11:20:38.493 回答
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。

于 2012-05-26T12:41:39.720 回答
0

我不完全理解你想要做什么,但很明显你根本不应该使用switch; 它不适用于您尝试实现的逻辑。

您可能会改为一系列if(...) else if (...)陈述。

于 2012-05-26T11:20:23.147 回答