使用枚举类支撑大括号初始化静态const unordered_map

时间:2019-07-17 15:28:08

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

在使用enum类作为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"}
};

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

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

完成新手的哈希运算,因此非常感谢外行的条款或代码段。

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

1 个答案:

答案 0 :(得分:0)

谢谢大家的帮助。

只想结束这一点,并说代码可以按您的建议很好地工作……在芯片外。

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

就像一个const一样运作良好,我不太可能有一个以上的对象实例,因此它不是静态的也没什么大问题。

再次感谢。