Переключатель C ++ / CLI в строке - PullRequest
3 голосов
/ 24 июня 2009

В других языках .NET, таких как C #, вы можете включить строковое значение:

string val = GetVal();
switch(val)
{
case "val1":
  DoSomething();
  break;
case "val2":
default:
  DoSomethingElse();
  break;
}

Похоже, что это не так в C ++ / CLI

System::String ^val = GetVal();
switch(val)  // Compile error
{
   // Snip
}

Есть ли специальное ключевое слово или другой способ заставить это работать для C ++ / CLI, как в C #?

Ответы [ 4 ]

5 голосов
/ 24 июня 2009

На самом деле вы можете использовать что угодно, кроме целых чисел (иногда обозначаемых целочисленными типами), если тестируемые объекты определяют преобразование в целое число.

Строковый объект не.

Однако вы можете создать карту со строковыми ключами (проверьте, что сравнение хорошо обработано) и указателями на классы, реализующие некоторый интерфейс в качестве значений:

class MyInterface {
  public:
    virtual void doit() = 0;
}

class FirstBehavior : public MyInterface {
  public:
    virtual void doit() {
      // do something
    }
}

class SecondBehavior : public MyInterface {
  public:
    virtual void doit() {
      // do something else
    }
}

...
map<string,MyInterface*> stringSwitch;
stringSwitch["val1"] = new FirstBehavior();
stringSwitch["val2"] = new SecondBehavior();
...

// you will have to check that your string is a valid one first...
stringSwitch[val]->doit();    

Немного долго для реализации, но хорошо продумано.

0 голосов
/ 05 декабря 2009

Я знаю, что мой ответ приходит слишком поздно, но я думаю, что это тоже хорошее решение.

struct ltstr {
    bool operator()(const char* s1, const char* s2) const {
        return strcmp(s1, s2) < 0;
    }
};

std::map<const char*, int, ltstr> msgMap;

enum MSG_NAMES{
 MSG_ONE,
 MSG_TWO,
 MSG_THREE,
 MSG_FOUR
};

void init(){
msgMap["MSG_ONE"] = MSG_ONE;
msgMap["MSG_TWO"] = MSG_TWO;
}

void processMsg(const char* msg){
 std::map<const char*, int, ltstr>::iterator it = msgMap.find(msg);
 if (it == msgMap.end())
  return; //Or whatever... using find avoids that this message is allocated in the map even if not present...

 switch((*it).second){
  case MSG_ONE:
   ...
  break:

  case MSG_TWO:
  ...
  break;

 }
}
0 голосов
/ 10 августа 2009

Я думаю, что нашел решение на codeguru.com .

0 голосов
/ 24 июня 2009

Вы, конечно, не можете использовать ничего, кроме целого числа в операторе switch в C / C ++. Самый простой способ сделать это в C ++ - использовать оператор if ... else:

std::string val = getString();
if (val.equals("val1") == 0)
{
  DoSomething();
}
else if (val.equals("val2") == 0)
{
  DoSomethingElse();
}

Edit:

Я только что заметил, что вы спросили о C ++ / CLI - я не знаю, применяется ли все вышеизложенное; это, безусловно, в ANSI C ++.

...