【问题标题】:Brace initialised static const unordered_map using enum class大括号使用枚举类初始化静态常量无序映射
【发布时间】:2019-07-17 15:28:08
【问题描述】:

我在使用枚举类作为 unordered_map 中的类型说明符时遇到问题。

我在互联网上搜索过,但没有找到任何解决方案。

我在下面的链接中找到了最接近的示例,但似乎不起作用。 Can't use enum class as unordered_map key

如果重要,可以在 STM32F4103 上运行。

foo.h

#include <cstring>
#include <unordered_map>
#include <functional>

class Foo
{
    public:
        enum class COLOURS : uint16_t
    {
        RED,
        YELLOW,
        BLUE,
        GREEN
    };
        static const std::unordered_map<COLOURS, std::string, EnumClassHash> colours_map;
};

foo.cpp

#include "foo.h"

struct EnumClassHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

std::unordered_map<Foo::COLOURS, std::string, EnumClassHash> Foo::colours_map
{
    {Foo::COLOURS::RED, "red"},
    {Foo::COLOURS::YELLOW, "yellow"},
    {Foo::COLOURS::BLUE, "blue"},
    {Foo::COLOURS::GREEN, "green"}
};

上面的编译很好,我省略了main,但基本上是构造类并获取与指定颜色关联的字符串。

但是,它会使芯片崩溃。我的怀疑是哈希计算不正确??

完全是哈希新手,因此非常感谢外行术语或代码 sn-p。

TIA

编辑:

非常感谢您到目前为止的帮助。问题仍然存在,但我现在可以更具体一些。

以下 foo.h 和相应的 empty foo.cpp 编译并运行良好:

foo.h

#include <unordered_map>
#include <cstdint>
#include <functional>
#include <string>

struct EnumClassHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

class Foo {
public:
    Foo() :
        colours_map(
                    {
                        {COLOURS::RED,      "red"},
                        {COLOURS::YELLOW,   "yellow"},
                        {COLOURS::BLUE,     "blue"},
                        {COLOURS::GREEN,    "green"}
                    }
                    )
    {
        ;
    }

    enum class COLOURS: uint16_t {
        RED,
        YELLOW,
        BLUE,
        GREEN
    };
    const std::unordered_map<COLOURS, std::string, EnumClassHash> colours_map;
};

但是,对于我的应用程序,我真的需要它是静态的。以下,编译正常但芯片崩溃。据我所知,使用 openOCD 芯片甚至无法启动。奇怪的是它在这里工作正常https://wandbox.org/permlink/xm37mOGjYFbOjc7I

foo.h

#include <unordered_map>
#include <cstdint>
#include <functional>
#include <string>

struct EnumClassHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

class Foo {
public:
    enum class COLOURS: uint16_t {
        RED,
        YELLOW,
        BLUE,
        GREEN
    };
    static const std::unordered_map<COLOURS, std::string, EnumClassHash> colours_map;
};

foo.cpp

#include "foo.h"

const std::unordered_map<Foo::COLOURS, std::string, EnumClassHash> Foo::colours_map {
    {Foo::COLOURS::RED, "red"},
    {Foo::COLOURS::YELLOW, "yellow"},
    {Foo::COLOURS::BLUE, "blue"},
    {Foo::COLOURS::GREEN, "green"}
};

...我觉得我遗漏了一些非常明显的东西。 TIA

【问题讨论】:

  • 如果在.cpp 中声明EnumClassHash 和在.hpp 中声明colours_map,如何编译?
  • 请更具体地了解崩溃发生的情况。初始化无序地图时会发生这种情况吗?
  • 你会遇到什么样的崩溃?如果您使用函数将每个值添加到映射,然后返回该映射以初始化 colours_map,是否会发生崩溃?
  • 经过几次修复后,wandbox.org/permlink/xm37mOGjYFbOjc7I 似乎可以正常工作(缺少#includeEnumClassHash 声明的位置错误)。你需要更具体。
  • 我的错误,错误的复制和粘贴。道歉。 EnumClassHash 在 .h 文件中。在这种情况下,看起来可能是其他东西使芯片崩溃。 @Holt 感谢那个 sn-p,不知道那个网站。很棒的工具!将从那里开始工作。非常感谢大家

标签: c++ dictionary c++17 unordered-map enum-class


【解决方案1】:

感谢大家对cmets的帮助。

只是想关闭它并说代码在您的建议中运行良好......芯片外。

问题似乎是当映射被声明为静态常量时,当创建使用它们的对象时,它会创建这些映射的副本(我假设在堆栈上??)。当仅声明为 const 时,使用它们的对象只是引用了 flash 而没有创建第二个“本地”副本。 非常奇怪,不知道为什么,对于静态的定义似乎是违反直觉的,但无论如何。可能是我的误会!

作为一个 const 效果很好,我不太可能拥有多个对象实例,所以它不是一个太大的问题,它也不是静态的。

再次感谢。

【讨论】:

    猜你喜欢
    • 2013-10-29
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多