如何在 C++ 中初始化私有静态 const 映射?
我只需要字典或关联数组 string
=> int
。
对于这种情况,有类型映射 C++。
但我只需要一张地图用于所有实例(-> static),并且该地图无法更改(-> const);
我用 boost 库找到了这种方法,
std::map<int, char> example =
boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
没有这个库还有其他解决方案吗? 我已经尝试过类似的方法,但是地图初始化总是存在一些问题。
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();
};
I need just dictionary or associative array string
=> int
.
There is type map C++ for this case.
But I need only one map forall instances(-> static) and this map can't be changed(-> const);
I have found this way with boost library
std::map<int, char> example =
boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
Is there other solution without this lib?
I have tried something like this, but there are always some issues with map initialization.
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();
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
C++11 标准引入了统一初始化,如果您的编译器支持的话,这会变得更加简单:
另请参阅 此部分来自 Professional C++,位于 unordered_maps 上。
The C++11 standard introduced uniform initialization which makes this much simpler if your compiler supports it:
See also this section from Professional C++, on unordered_maps.
如果您发现
boost::assign::map_list_of
很有用,但由于某种原因无法使用它,您可以编写你自己的:了解这些东西是如何工作的很有用,特别是当它们很短时,但在这种情况下我会使用一个函数:
a.hpp
a.cpp
If you find
boost::assign::map_list_of
useful, but can't use it for some reason, you could write your own:It's useful to know how such things work, especially when they're so short, but in this case I'd use a function:
a.hpp
a.cpp
无需 C++11 即可正常工作
Works fine without C++11
如果映射仅包含编译时已知的条目并且映射的键是整数,那么您根本不需要使用映射。
If the map is to contain only entries that are known at compile time and the keys to the map are integers, then you do not need to use a map at all.
解决问题的另一种方法:
这更有效,因为没有从堆栈到堆的单一类型复制(包括所有元素的构造函数、析构函数)。这是否重要取决于您的用例。和弦没关系! (但你可能会也可能不会发现这个版本“更干净”)
A different approach to the problem:
This is more efficient, as there is no one-type copy from stack to heap (including constructor, destructors on all elements). Whether this matters or not depends on your use case. Does not matter with strings! (but you may or may not find this version "cleaner")
您可以尝试以下操作:
MyClass.h
MyClass.cpp
通过此实现,您的类常量静态映射是私有成员,并且可以使用公共 get 方法被其他类访问。否则
由于它是常量且无法更改,因此您可以删除公共 get 方法
并将映射变量移动到类的公共部分。然而,如果需要继承和/或多态性,我会将 createMap 方法保留为私有或受保护。以下是一些使用示例。
我编辑了我原来的帖子,我发布的原始代码没有任何问题,它编译、构建和运行正确,只是
我作为答案提出的第一个版本是地图被声明为公共的,并且地图是常量但不是静态的。
You could try this:
MyClass.h
MyClass.cpp
With this implementation your classes constant static map is a private member and can be accessible to other classes using a public get method. Otherwise
since it is constant and can not change, you can remove the public get method
and move the map variable into the classes public section. I would however leave the createMap method private or protected if inheritance and or polymorphism is required. Here are some samples of use.
I had edited my original post, there was nothing wrong with the original code in which I posted for it compiled, built and ran correctly, it was just that
my first version I presented as an answer the map was declared as public and the map was const but wasn't static.
如果您使用的编译器仍然不支持通用初始化,或者您对使用 Boost 有保留,另一种可能的替代方案如下
If you are using a compiler which still doesn't support universal initialization or you have reservation in using Boost, another possible alternative would be as follows
您可以使用单例模式来实现此目的。
然后你可以像这样使用你的地图
You can use the singleton pattern for this.
You can then use your map like this
函数调用不能出现在常量表达式中。
试试这个:(只是一个例子)
A function call cannot appear in a constant expression.
try this: (just an example)
我经常使用这种模式,并建议您也使用它:
当然它的可读性不是很好,但如果没有其他库,我们可以做到最好。
此外,不会有任何冗余操作,例如像您的尝试那样从一张地图复制到另一张地图。
这在函数内部更有用:
而不是:
使用以下内容:
不仅您不再需要在这里处理布尔变量,而且如果已经调用了函数内静态变量的初始值设定项,您将不会检查隐藏的全局变量。
I often use this pattern and recommend you to use it as well:
Sure it is not very readable, but without other libs it is best we can do.
Also there won't be any redundant operations like copying from one map to another like in your attempt.
This is even more useful inside of functions:
Instead of:
Use the following:
Not only you don't need here to deal with boolean variable anymore, you won't have hidden global variable that is checked if initializer of static variable inside function was already called.