插入std::map时强制初始化为0
我有一个std::map<std::string,std::size_t>键映射计数器。当我增加一个计数器时,我不知道它是否已经存在。如果是,则递增。如果不是,则设置为 1。这很容易做到:
std::map<std::string,std::size_t> counters;
//...
auto c_it = counters.find(key);
if(c_it == counters.end())
counters.insert(key,1);
else
(*c_it)++;
这是一个简单的事情的很多代码......我想这样做:
counters[key]++;
但这会产生未定义的行为,因为std::size_t()在映射中不存在计数器时调用,并且不能保证std::size_t()初始化为 0。
我看到了两个潜在的解决方案:
- 查找/创建类似于
std::size_t使用默认构造函数创建时强制初始化为 0的类型。std或 中有这样的类型boost吗? - 查找/创建一个专用分配器来替换
std::allocator<std::pair<const Key,T>>作为std::map. 但我不知道该怎么做。
注意:我只使用 C++11(我不想要 C++>=14 的解决方案)
回答
++counters[key];是完全有效的。std::map::operator[]如果键在映射中不存在,则插入一个值初始化的元素。这是做你解释的事情的惯用方式。
回答
但这会产生未定义的行为,因为
std::size_t()在映射中不存在计数器时调用,并且不能保证std::size_t()初始化为 0。
这个假设是不正确的。来自cppreference 的引用:
如果执行插入,则映射值是值初始化的(为类类型默认构造,否则为零初始化)并返回对它的引用。
引用是针对 C++11 之前的版本,但更容易理解元组魔术和可观察效果是相同的。
该值将被初始化为零,您可以counters[key]++;毫无问题地使用。