C++14 静态 class 映射初始化

C++14 Static class map initialization

现在我正在创建一个静态 class(是的,c++ 没有静态 classes,但据我所知,使用私有构造函数创建一个 class同样的结果)像下面这样 return给我一张地图:

class Foo()
{
public:
    static std::map<MyEnum, SomeInfo> getMap()
    {
        static const std::map<MyEnum, SomeInfo> fooMap
        {
            {MyEnum::Enum1, SomeInfo{ "info1", "Info 1" }},
            {MyEnum::Enum2, SomeInfo{ "info2", "Info 2" }},
        }
        return fooMap;
    }
}

struct SomeInfo
{
    std::string id;
    std::string name;
}

这种方法可能会很频繁,在我看来这看起来不是很有效,因为每次都创建一个新的地图实例然后 return 它。我尝试创建一个 static const std::map 并按以下方式对其进行初始化:

class Foo()
{
public:
    static const std::map<MyEnum, SomeInfo> fooMap
    {
        {MyEnum::Enum1, SomeInfo{ "info1", "Info 1" }},
        {MyEnum::Enum2, SomeInfo{ "info2", "Info 2" }},
    }
}

但是这个 return 出现以下错误:类型 'const std::map<MyEnum, SomeInfo>' 的静态数据成员必须在行外初始化

我真的不知道该怎么做,经过一些研究我没有发现任何真正有用的东西..

有什么猜测吗?

在此先感谢大家!

您需要在“声明”地图后“定义”地图: 参见:https://en.cppreference.com/w/cpp/language/static

#include <map>
#include <string>

struct SomeInfo
{
    std::string id;
    std::string name;
};

enum MyEnum {
    Enum1, Enum2

};

class Foo
{
private:
    static const std::map<MyEnum, SomeInfo> fooMap;
public:
    static std::map<MyEnum, SomeInfo> getMap()
    {
        return fooMap;
    }
};

const std::map<MyEnum, SomeInfo> Foo::fooMap = {
    {MyEnum::Enum1, SomeInfo{ "info1", "Info 1" }},
    {MyEnum::Enum2, SomeInfo{ "info2", "Info 2" }}
};


int main(){
    auto val = Foo::getMap()[MyEnum::Enum1];
    return 0;
}

如果你想让你的类型不可构造,你可以通过 Foo() = delete; 删除编译器生成的默认构造函数 - 它不能是私有的。

当你声明一个静态成员变量时,它的space并没有分配给它,你只是声明它。您必须在 class 实现中为 static 变量分配 space。在 C++17 中,您可以使用 static inline,但在此之前,您必须为静态变量分配 space,如下所示:

   class Something {
   private:
    static const std::map<MyEnum, SomeInfo> map_data;

   public:
    static std::map<MyEnum, SomeInfo> getMap() { return map_data; }
};

const std::map<MyEnum, SomeInfo> Something::map_data = {
    {MyEnum::Enum1, SomeInfo{"info1", "Info 1"}},
    {MyEnum::Enum2, SomeInfo{"info2", "Info 2"}},
}