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