2009-06-23 2 views
3

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

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#?

+0

Я также считаю, что это верно для Java, то есть без переключения строк. –

ответ

5

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

Объект String этого не делает.

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

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

Это действительно приятное решение, спасибо. –

0

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

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

Edit:

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

+0

включение строк в C# - это отчасти просто синтаксический сахар. при включении int компилятор использует таблицу переходов со значением int, используемого в качестве ключа, при включении строки результирующий двоичный код повторно принимает if-if-else-else (это никоим образом не идентично) –

+0

Фактически, когда при включении строки компилятор C# также создает таблицу перехода. См. Http://stackoverflow.com/questions/395618/if-else-vs-switch – heavyd

0

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

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; 

} 
}