【问题标题】:Enumerations in C++ with raw values?C ++中的枚举与原始值?
【发布时间】:2019-11-01 06:14:35
【问题描述】:

C++ 中的枚举是否可以有原始值?

Swift 示例:

enum AnOperations: String {
    case Addition = "+"
    case Subtraction = "-"
    case Division = "/"
}

// if or switch
if AnOperations.Addition.rawValue == "+" {
    print("true")
}

【问题讨论】:

  • 什么是“原始值”?
  • 在 C 中,必须将枚举分配给一个 int(我相信)。在 Swift 中,您可以将其分配给字符串、字符或任何整数或浮点类型的值。这对于 C++ 是否可能用于字符串并且可以用于与另一个字符串进行比较(即如果 Addition (an enum) == "+")
  • 您的示例使用由单个字符组成的字符串。如果将它们更改为字符(“+”而不是“+”),它将起作用,因为字符是整数。如果您需要字符串,则必须将它们放入字符串函数映射中。
  • 您正在寻找的可能是 std::unordered_map

标签: c++


【解决方案1】:

我必须承认,除了它的名字,我对Swift 一无所知。

在 C++ 中,字符串不能用于枚举。

Enumeration Declaration:

枚举是一种独特的类型,其值被限制在一个值范围内(详见下文),其中可能包括几个显式命名的常量(“枚举数”)。常量的值是 integral 类型的值,称为枚举的基础类型。

(强调我的。)

什么可能有效:

enum AnOperations: char {
  Addition = '+',
  Subtraction = '-',
  Division = '/'
};

因为char 是整数类型之一。

示例:

#include <iostream>
#include <sstream>

int main()
{
  enum AnOperations: char {
    Addition = '+',
    Subtraction = '-',
    Division = '/'
  };
  std::string text = "1 + 2";
  std::istringstream in(text);
  int arg1, arg2, result; char op;
  in >> arg1 >> op >> arg2;
  switch (op) {
    case Addition: result = arg1 + arg2; break;
    case Subtraction: result = arg1 - arg2; break;
    case Division: result = arg1 / arg2; break;
    default:
      std::cerr << "Unknown op. '" << op << "'!\n";
      return 1;
  }
  std::cout << arg1 << ' ' << op << ' ' << arg2 << " = " << result << '\n';
  return 0;
}

输出:

1 + 2 = 3

Live Demo on coliru

【讨论】:

  • 有没有办法检查枚举“值”是否存在? (即 AnOperations.contains("+")?
  • 恐怕不行。我记得大概有一个关于这个的很好的 Q/A,但我必须深入挖掘一下。
  • 那太好了!谢谢!
  • @HelloWorld 我发现了这个:SO: How to check if enum value is valid?。如何确保在switch() 中考虑所有enum 值?这并不容易 - 不受语言本身的支持。我记得gcc 有一个可以启用的警告。
  • 嗯,很高兴知道!最坏的情况,我会继续使用 if 语句。
【解决方案2】:

您可以在 C++ 中使用 char 类型。
以下作品

enum AnOperations : char {
    ADDITION='+',
    SUBSTRACTION='-',
    DIVISION='/'
};

编译时出现以下错误

enum AnOperationsSTR : std::string {
    ADDITION = '+',
    SUBSTRACTION = '-',
    DIVISION = '/'
};
or
enum AnOperationsSTR : char[] {
    ADDITION = '+',
    SUBSTRACTION = '-',
    DIVISION = '/'
};

所以,你可以像下面这样使用。

int main(void)
{
    printf("is %c == AnOperations:'+' : %s\n", '+', AnOperations::ADDITION == '+' ? "TRUE" : "FALSE");
    printf("is %c == AnOperations:'+' : %s\n", '+', AnOperations::SUBSTRACTION == '+' ? "TRUE" : "FALSE");
    return 0;
}

上面代码的结果是,

is + == AnOperations:'+' : TRUE
is + == AnOperations:'+' : FALSE

【讨论】:

    【解决方案3】:

    正如其他人已经说过的,您无法打开字符串,但您可以使用地图来实现相同的结果。根据您的目的,这可能是矫枉过正。

    void f( const char* s )
    {
      using function_t = std::function< void() >;
      using string_to_function = map< string, function_t >;
    
      static string_to_function m =
      {
        {"1234", f_1234}, // assosciate "1234" to function f_1234
        {"ABCD", f_ABCD}, // assosciate "ABCD" to function f_ABCD
      };
    
      auto i = m.find( s );
    
      return i == m.end()
        ? f_default() // not found in map
        : i->second(); // found, so we call the function
    }
    

    Demo

    而且,只是为了好玩,试试这个:

    #include <iostream>
    
    void f( int i )
    {
      switch ( i )
      {
      default: cout << "default"; break;
      case 'ABCD': cout << "ABCD\n"; break;
      case '1234': cout << "1234\n"; break;
      }
    }
    
    int main()
    {
      f( '1234' );
      f( 'ABCD' );
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多