Home > OS >  C 14 Static class map initialization
C 14 Static class map initialization

Time:11-21

right now I'm creating a static class (yes, c does not have static classes, but to my knowledge creating a class with a private constructor gives the same result) like the following returning to me a map:

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;
}

This method may very frequently, in my opinion this doesn't look very efficient because everytime create a new istance of a map then return it. I've tried to create a static const std::map instead and initialize it in the following way:

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

but this returns the following error: Static data member of type 'const std::map<MyEnum, SomeInfo>' must be initialized out of line

I've really no idea how to do that, after some research I didn't find anything really helpful..

Any guesses?

Thanks in advance to everyone!

CodePudding user response:

You need to "define" your map after you "declared" it: See: 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;
}

And if you want to make your type not constructable you can delete the compiler generated default constructor via Foo() = delete; - it must not be private.

CodePudding user response:

When you declare a static member variable, the space for it is not allocated for it, you just declare it. You have to allocate space for static variable in the class implementation. In C 17 you can use static inline but prior to that you have to allocate space for you static variable like this:

   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"}},
}
  • Related