【问题标题】:C++/CLI switch on StringC++/CLI 开启字符串
【发布时间】:2009-06-23 22:17:54
【问题描述】:

在其他 .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# 中一样工作?

【问题讨论】:

  • 我也相信 Java 也是如此,即没有切换字符串。

标签: .net string c++-cli switch-statement


【解决方案1】:

实际上,如果测试对象定义了转换为整数,您可以使用除整数以外的任何内容(有时由整数类型指定)。

字符串对象没有。

但是,您可以使用字符串键(检查比较是否处理良好)和指向实现某些接口作为值的类的指针来创建映射:

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();    

实现起来有点长,但设计得很好。

【讨论】:

    【解决方案2】:

    在 C / C++ 的 switch 语句中,您当然不能使用除整数以外的任何内容。在 C++ 中最简单的方法是使用 if ... else 语句:

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

    编辑:

    我刚刚发现您询问了 C++/CLI - 我不知道以上是否仍然适用;在 ANSI C++ 中当然可以。

    【讨论】:

    • 在 c# 中打开字符串部分只是语法糖。当打开一个 int 时,编译器使用一个跳转表,其中 int 的值用作键,当打开一个字符串时,生成的二进制文件类似于 if-if-else-else(但绝不相同)
    • 实际上,当打开一个字符串时,C# 编译器也会生成一个跳转表。见stackoverflow.com/questions/395618/if-else-vs-switch
    【解决方案3】:

    我想我在codeguru.com 上找到了解决方案。

    【讨论】:

      【解决方案4】:

      我知道我的回答来得太晚了,但我认为这也是一个很好的解决方案。

      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;
      
       }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        • 1970-01-01
        • 2017-07-28
        • 2017-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多