新的 std::map 条目是如何仅通过键插入来初始化的?

How are new std::map entries initialized just by key insertion?

我有一个 std::vector<MyString> 数据不是唯一的。实际上,大多数字符串都是重复的。而且我必须找到唯一的和它们的重复编号。

我使用地图:

std::map<MyString,unsigned short> stringsMap;
.......
if ( stringsMap.find( currentString ) == stringsMap.end() )
{
    stringsMap[ currentString ] = 0;
}

stringsMap[ currentString ]++;
........

您是否知道如何在更少的行上完成它?

它可以在一行上完成:stringsMap[ currentString ]++; 但是默认情况下 short 具有不确定的值。

It could be done on one row: stringsMap[ currentString ]++; however short has indeterminate value by default.

这不是真的,值在 documentation:

中明确定义

If an insertion is performed, the mapped value is value-initialized (default-constructed for class types, zero-initialized otherwise) and a reference to it is returned.

重点是我的。

所以写一个liner就完美了:

stringsMap[ currentString ]++;

这是常见的做法,甚至在文档中作为示例给出:

// count the number of occurrences of each word
// (the first call to operator[] initialized the counter with zero)
std::map<std::string, size_t>  word_map;
for (const auto &w : { "this", "sentence", "is", "not", "a", "sentence",
                       "this", "sentence", "is", "a", "hoax"}) {
    ++word_map[w];
}

however short has indeterminate value by default.

没有。对于不存在的键,映射将使用 T() 来初始化新创建的条目的值,对于 unsigned short,它有效地评估为 0

参见std::map::operator[] documentation(强调我的1):

1) Inserts value_type(key, T()) if the key does not exist. This function is equivalent to return insert(std::make_pair(key, T())).first->second;
- key_type must meet the requirements of CopyConstructible.
- mapped_type must meet the requirements of CopyConstructible and DefaultConstructible.
If an insertion is performed, the mapped value is value-initialized (default-constructed for class types, zero-initialized otherwise) and a reference to it is returned.

因此,只写

std::map<MyString,unsigned short> stringsMap;
.......
stringsMap[ currentString ]++;

完全没问题。整个 if 块是多余的,不需要。


1)这不是真的,这是@Remy Lebau的强调