【问题标题】:std::unordered_map using enum and defined classstd::unordered_map 使用枚举和定义的类
【发布时间】:2016-04-04 16:38:52
【问题描述】:

我正在尝试使用 enum class 作为键和定义的类作为引用对象来定义 std::unordered_map

std::unordered_map<Dimension, unit, EnumClassHash> SI_Dim;
SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram;

Dimension 是一个enum class,在单独的头文件中声明为

enum class Dimension{MASS, TIME, LENGTH, TEMPERATURE, CURRENT, QUANTITY, ANGLE, FORCE, ENERGY, POWER,
                 AREA, VOLUME, NONDIMENSIONAL};

使用EnumClassHash 作为散列函数(如果相关,我可以发布代码)。

BaseSIUnits::kilogram 在上面几行定义为

const unit BaseSIUnits::kilogram = unit(1, "kg", Dimension::MASS);

编译得很好。但是SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram; 行给了我一个错误。在 QtCreator(我的 IDE)中,它说“需要声明”,而 g++ 给出错误“SI_Dim 没有命名类型”。这些对我来说都没有任何意义。此外,当查看 QtCreator 中的行时,Dimension::MASSBaseSIUnits::kilogram 均未突出显示(几乎就像它们未被识别,即使我知道它们是)。我对 std::unordered_map 没有太多经验,所以这可能是我遗漏的一些简单语法错误。但是根据我看过的例子,语法对我来说是正确的。

【问题讨论】:

  • 对不起,我想这里的问题还不清楚。我的问题是是否存在明显的语法错误导致代码无法编译。
  • 你在函数之外有SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram;这一行吗?您不能只在命名空间范围内拥有任意代码。
  • 我确实在函数之外拥有它。我希望可以从其他文件访问 unordered_map 容器。我该怎么做?
  • 一种选择是使用列表初始化 - std::unordered_map&lt;Dimension, unit, EnumClassHash&gt; SI_Dim{{Dimension::MASS, BaseSIUnits::kilogram}};
  • 编译得很好!谢谢!

标签: c++ class c++11 enums unordered-map


【解决方案1】:

正如 Praetorian 在评论中指出的那样,您不能在 C++ 中的函数之外真正拥有代码(初始化全局/静态变量除外)。如果您需要这样的代码(即不能编写为初始化的代码),那么您可以编写一个函数init_si_dim,它需要在使用前调用(一次)。请参阅this question,了解通过在构造函数中进行初始化的临时类的全局对象自动执行此操作的方法。

在另一个方向上,为您的enum 类型使用无序映射似乎有点奇怪。鉴于您的值很少,并且没有为enum 值分配特定的整数值,我认为您最好使用随机访问容器,例如通过std::array

考虑下面的代码

#include <array>                                                                                                                            

enum class dimension{mass, time, length};

inline constexpr std::size_t dimension_to_index(dimension d)
{
    return static_cast<std::size_t>(d) - static_cast<std::size_t>(dimension::mass);
}

struct foo{};

std::array<foo, 1 + dimension_to_index(dimension::length)> v;

int main()
{
    v[dimension_to_index(dimension::time)];
}   

我们首先有enum,然后是一个将其值转换为索引的安全函数。然后我们定义一个array 对象。正如您在main 中看到的,现在可以通过enum 值访问array 元素。

【讨论】:

  • 有趣。我会看看这两种选择。
猜你喜欢
  • 2013-09-21
  • 2021-11-21
  • 2015-11-22
  • 1970-01-01
  • 2013-06-25
  • 2015-09-03
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多