1

私のスイッチでは、number_of_cases-1自分で数字を書かずに、ケースを0から()に変更したいと思います。そのため、途中で1つのケースブロックを削除すると、次のケースの番号が付け直され(1ずつ減り)、スイッチが再びfrom(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のヒントをありがとう、私はちょうどケース値がコンパイル時に知られているので、スイッチを使用する方が良いだろうと思いました。

そして、私がやりたいことを指定するには:メニューがありますchar[rows][cols]={"first line","second line"}。スイッチケースを行にマップしたいので、メニューから行を削除したい場合(行番号に続いて減少します)、プログラムの残りの部分で1つのケースを削除します。

4

5 に答える 5

2

プリプロセッサには状態保持構造はありません。ただし、C ++ 11では、ラムダを使用して個々のケースを表現し、それらを配列に入れて、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

一連の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 に答える
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頭に浮かぶ。

于 2012-05-26T11:27:58.007 に答える
0

私はあなたが何をしたいのか完全には理解していませんが、あなたが単に使用すべきではないことは明らかですswitch; 実装しようとしているロジックを対象としたものではありません。

代わりに、おそらく一連のif(...) else if (...)ステートメントです。

于 2012-05-26T11:20:23.147 に答える
0

Boostプリプロセッサライブラリは、コンパイル時に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 に答える