【问题标题】:Keys to access vector fields - enum class or enum in namespace?访问向量字段的键-命名空间中的枚举类或枚举?
【发布时间】:2017-08-02 10:21:40
【问题描述】:

假设我有一个向量的别名:

typedef std::vector<double> PlanetData;

我希望它的字段可以通过一些键访问:

double x = planet_data[PlanetDataKeys::PosX]; //planet_data is of type PlanetData

我怎样才能实现它?

我可以在命名空间中定义一个枚举:

namespace PlanetDataKeys {
  enum {
    PosX = 0,
    PosY = 1
  };
}

但是enum class 更安全:

enum class PlanetDataKeys {
  PosX = 0,
  PosY = 1
};

但是,由于 enum classint 类型的隐式转换被禁用,这需要编写:

double x =  planet_data[static_cast<int>(PlanetDataKeys::PosX)];

这有点尴尬。

在这种情况下哪种方法更好,为什么?

编辑对锯齿向量的一些解释:

在实际代码中,PlanetData 有大约 7 个字段,如果我决定扩展它可能会更多。我在解析data_string = "date: 2903248.12343, position=[124543254.1343214,123213.12341,63456.1234], velocity=[..." 形式的字符串时创建了它的一个实例。这就是为什么我希望它成为一个向量:使用类似planet_data.push_back(ParseNextDouble(data_string));

【问题讨论】:

  • enum class 唯一更安全的一点是缺少从枚举到底层类型的隐式转换,这是您遇到的问题。因此我只会在命名空间中使用普通的enum
  • @HolyBlackCat 这是唯一的事情吗?防止重新定义键不是另一个吗?
  • 你真的有一个总是大小为 2 的 std::vector 吗?
  • @PrzemysławCzechowski 你能详细说明一下吗?如果您在谈论具有重复值的枚举器,他们seem to be allowed
  • @bolov 不,实际上它的大小约为 7,也许更大。我想在解析数据时使用简单的push_back 放入

标签: c++ c++11 vector enums enum-class


【解决方案1】:

请不要期望一个不起眼的矢量提供太多功能。

Vector 并非旨在使用索引以外的键访问其数据。尽管您的示例在语法和语义上都是正确的,但它们看起来像是对 std::vector 和枚举类的滥用。每个工具都有其用途,而矢量似乎不是最适合您的任务。

引入枚举类以提高类型安全性。有了它们,您将永远不会混淆PlanetDataKeysSatelliteEphemerisKeplerianOrbitElements。但是在您的情况下,您最终将它们中的任何一个转换为 int,从而失去了对类型安全枚举的所有征服。

对我来说,最好定义一个带有下标运算符的PlanetData 类,它接受PlanetDataKeys 作为它的参数。

如果您想坚持使用向量,我会选择第一个变体(带有命名空间)。它更容易读写,而且我相信它甚至不比以这种方式使用的枚举类更安全。

【讨论】:

    【解决方案2】:

    只定义适当类型的作用域常量怎么样,像这样:

    namespace PlanetDataKeys {
      const size_t PosX = 0;
      const size_t PosY = 1;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2014-07-24
      • 1970-01-01
      • 2011-10-28
      • 2011-07-08
      相关资源
      最近更新 更多