如何在C ++中初始化私有静态常量映射?
我只需要字典或关联数组string
=> int
。
这种情况下有types映射C ++。
但是我只需要一个map实例( – > static),这个map不能改变( – > const);
我用boost库find了这个方法
std::map<int, char> example = boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
有没有这个lib的其他解决scheme? 我已经尝试了这样的事情,但总是有一些地图初始化的问题。
class myClass{ private: static map<int,int> create_map() { map<int,int> m; m[1] = 2; m[3] = 4; m[5] = 6; return m; } static map<int,int> myMap = create_map(); };
#include <map> using namespace std; struct A{ static map<int,int> create_map() { map<int,int> m; m[1] = 2; m[3] = 4; m[5] = 6; return m; } static const map<int,int> myMap; }; const map<int,int> A:: myMap = A::create_map(); int main() { }
C ++ 11标准引入了统一的初始化,如果你的编译器支持它,那么这个标准就变得简单了:
//myClass.hpp class myClass { private: static map<int,int> myMap; };
//myClass.cpp map<int,int> myClass::myMap = { {1, 2}, {3, 4}, {5, 6} };
另请参阅专业C ++中的unordered_maps部分。
如果你发现boost::assign::map_list_of
有用,但由于某种原因不能使用它,你可以编写自己的 :
template<class K, class V> struct map_list_of_type { typedef std::map<K, V> Map; Map data; map_list_of_type(K k, V v) { data[k] = v; } map_list_of_type& operator()(K k, V v) { data[k] = v; return *this; } operator Map const&() const { return data; } }; template<class K, class V> map_list_of_type<K, V> my_map_list_of(K k, V v) { return map_list_of_type<K, V>(k, v); } int main() { std::map<int, char> example = my_map_list_of(1, 'a') (2, 'b') (3, 'c'); cout << example << '\n'; }
知道这些东西是如何工作是很有用的,特别是当它们太短时,在这种情况下,我会使用一个函数:
a.hpp
struct A { static map<int, int> const m; };
a.cpp
namespace { map<int,int> create_map() { map<int, int> m; m[1] = 2; // etc. return m; } } map<int, int> const A::m = create_map();
我做的! 🙂
没有C + + 11工作正常
class MyClass { typedef std::map<std::string, int> MyMap; struct T { const char* Name; int Num; operator MyMap::value_type() const { return std::pair<std::string, int>(Name, Num); } }; static const T MapPairs[]; static const MyMap TheMap; }; const MyClass::T MyClass::MapPairs[] = { { "Jan", 1 }, { "Feb", 2 }, { "Mar", 3 } }; const MyClass::MyMap MyClass::TheMap(MapPairs, MapPairs + 3);
如果地图只包含在编译时已知的条目,并且地图的键是整数,则根本不需要使用地图。
char get_value(int key) { switch (key) { case 1: return 'a'; case 2: return 'b'; case 3: return 'c'; default: // Do whatever is appropriate when the key is not valid } }
解决问题的另一种方法是:
struct A { static const map<int, string> * singleton_map() { static map<int, string>* m = NULL; if (!m) { m = new map<int, string>; m[42] = "42" // ... other initializations } return m; } // rest of the class }
这样更有效率,因为没有从堆栈到堆的单一types副本(包括构造函数,所有元素上的析构函数)。 这是否重要取决于您的使用情况。 与弦无关! (但你可能会或可能不会觉得这个版本“更清洁”)
如果您使用的编译器仍然不支持通用初始化,或者您在使用Boost时有保留,另一种可能的替代方法如下所示
std::map<int, int> m = [] () { std::pair<int,int> _m[] = { std::make_pair(1 , sizeof(2)), std::make_pair(3 , sizeof(4)), std::make_pair(5 , sizeof(6))}; std::map<int, int> m; for (auto data: _m) { m[data.first] = data.second; } return m; }();
你可以试试这个:
MyClass.h
class MyClass { private: static const std::map<key, value> m_myMap; static const std::map<key, value> createMyStaticConstantMap(); public: static std::map<key, value> getMyConstantStaticMap( return m_myMap ); }; //MyClass
MyClass.cpp
#include "MyClass.h" const std::map<key, value> MyClass::m_myMap = MyClass::createMyStaticConstantMap(); const std::map<key, value> MyClass::createMyStaticConstantMap() { std::map<key, value> mMap; mMap.insert( std::make_pair( key1, value1 ) ); mMap.insert( std::make_pair( key2, value2 ) ); // .... mMap.insert( std::make_pair( lastKey, lastValue ) ); return mMap; } // createMyStaticConstantMap
在这个实现中,类常量静态映射是一个私有成员,可以使用公共get方法访问其他类。 否则,因为它是不变的,不能改变,你可以删除public get方法,并将mapvariables移动到public类的公共部分。 不过,如果需要inheritance和/或多态性,我会将createMap方法保留为private或protected。 这里有一些使用的样本。
std::map<key,value> m1 = MyClass::getMyMap(); // then do work on m1 or unsigned index = some predetermined value MyClass::getMyMap().at( index ); // As long as index is valid this will // retun map.second or map->second value so if in this case key is an // unsigned and value is a std::string then you could do std::cout << std::string( MyClass::getMyMap().at( some index that exists in map ) ); // and it will print out to the console the string locted in the map at this index. //You can do this before any class object is instantiated or declared. //If you are using a pointer to your class such as: std::shared_ptr<MyClass> || std::unique_ptr<MyClass> // Then it would look like this: pMyClass->getMyMap().at( index ); // And Will do the same as above // Even if you have not yet called the std pointer's reset method on // this class object. // This will only work on static methods only, and all data in static methods must be available first.
我编辑了我原来的post,原来的代码没有错,我发布了它编译,构build和正确运行,这只是我提出的第一个版本作为答案地图被宣布为公共和地图是const,但不是静态的。
函数调用不能出现在常量expression式中。
试试这个:(只是一个例子)
#include <map> #include <iostream> using std::map; using std::cout; class myClass{ public: static map<int,int> create_map() { map<int,int> m; m[1] = 2; m[3] = 4; m[5] = 6; return m; } const static map<int,int> myMap; }; const map<int,int>myClass::myMap = create_map(); int main(){ map<int,int> t=myClass::create_map(); std::cout<<t[1]; //prints 2 }
我经常使用这种模式,并build议您使用它:
class MyMap : public std::map<int, int> { public: MyMap() { //either insert(make_pair(1, 2)); insert(make_pair(3, 4)); insert(make_pair(5, 6)); //or (*this)[1] = 2; (*this)[3] = 4; (*this)[5] = 6; } } const static my_map;
当然这不是很可读,但没有其他的库,最好我们可以做。 此外,不会有任何多余的操作,如从您的尝试像从一张地图复制到另一个。
这在function内更有用:代替:
void foo() { static bool initComplete = false; static Map map; if (!initComplete) { initComplete = true; map= ...; } }
使用以下内容:
void bar() { struct MyMap : Map { MyMap() { ... } } static mymap; }
不仅你不需要在这里处理布尔variables,你将不会有隐藏的全局variables,如果已经调用函数内部的静态variables的初始化方法,那么将检查它。