【问题标题】:how to use boolean expression in switch in C++如何在 C++ 中的 switch 中使用布尔表达式
【发布时间】:2014-06-03 14:43:55
【问题描述】:

我需要将if else转换成switch语句,请帮忙:

if (XMLString::compareString(xmlch_Title, XMLString::transcode("abc")) == 0 ) {
    out_Config.abc = XMLString::transcode(xmlch_Value);
} else if (XMLString::compareString(xmlch_Title, XMLString::transcode("def")) == 0 ) {
    out_Config.def = XMLString::transcode(xmlch_Value);
} .......

【问题讨论】:

  • 它(大概)是正确的,并且没有将其转换为switch 语句的好方法。 (可能您可以构造一些可以在switch 中使用的人工离散值,但结果会很复杂,并不比if 好)。为什么需要转换它?

标签: c++ visual-c++ switch-statement


【解决方案1】:

注意:在您的情况下,使用布尔表达式作为 switch 的条件几乎没有用处,因为您只能有两种可能的结果switch 语句

转到"case true: ",或"case false: "


简介

如标准 (n3797) 中所述,与 switch 一起使用的条件必须可以隐式转换为整数或枚举类型。

6.4.2p2 switch语句 [stmt.switch]

条件应为整数类型、枚举类型或类类型。如果是类类型,则条件在上下文中隐式转换(第 4 条)为整数或枚举类型**。进行整体促销。 switch 语句中的任何语句都可以用一个或多个 case 标签进行标记,如下所示:

case constant-expression:

其中常量表达式应该是转换条件的提升类型的转换常量表达式(5.19)。同一个 switch 中的任何两个 case 常量在转换为 switch 条件的提升类型后都不应具有相同的值。


这意味着下面的理论实现是不正确的,因为std::string 不能隐式转换为整数或枚举类型(1),而且它也不能用于一个常量表达式 (2).

std::string get_string ();

switch (get_string ()) {            //          (1)
  case std::string ("stack"): ...;  // <----.
  case std::string ( "over"): ...;  // <----|-- (2)
  case std::string ( "flow"): ...;  // <----'
}



我完全不走运了吗?

并非如此,如果您要使用 hashing function 为所涉及的 字符串 生成 hash,理论上您可以使用 switch;请注意上述哈希的潜在冲突。

另请注意,对于 case-labelsconstant-expressions 中必须有一个可用的实现。

是否值得编写如此复杂的代码来解决此类问题?应该不会吧。

【讨论】:

    【解决方案2】:

    如果您想排除公共部分,您可能需要使用包含转码字符串常量的结构数组和执行 then 操作的 lambda。大致如下:

    #include <functional>
    
    struct check_case {
      const XMLString code;
      const std::function <void (Config &, const XMLString &)> handler;
    };
    
    check_case check_list[2] = {
      {XMLString::transcode("abc"), [](Config &out_Config, const XMLString &code) { out_Config.abc = code;}},
      {XMLString::transcode("def"), [](Config &out_Config, const XMLString &code) { out_Config.def = code;}},
    };
    
    for (auto c : check_list) {
       if (XMLString::compareString(xmlch_Title,c.code) == 0){ 
         c.handler(out_Config, XMLString::transcode(xmlch_Value));
         break;
       }
    }
    

    虽然它仍然很冗长,我不确定你会发现它更容易阅读。此外,您无法像使用普通开关那样级联处理程序(这可能是您提出问题的最初原因)。

    或者,您可以将所有这些嵌入到一个专用类中,这样更容易构建上下文(类实例成员字段)。在那里手动级联方法会更容易。如上所述,可读性也不是很理想。

    【讨论】:

    • 另外,这个blog post 可能有用吗?
    • 非常感谢大家的回复。
    【解决方案3】:

    从不同的角度来看它。分两个阶段做... 第 1 阶段:提取引号“abc”或“def”中的文本 第 2 阶段:切换(基于第 1 阶段的变量)和案例将提供实施

    【讨论】:

      猜你喜欢
      • 2014-11-06
      • 2012-08-26
      • 2017-02-08
      • 2020-04-30
      • 2012-01-23
      • 2012-05-17
      • 2017-12-26
      相关资源
      最近更新 更多