简体   繁体   English

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

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

I have one std::vector<MyString> which data is not unique. 我有一个std::vector<MyString> ,该数据不是唯一的。 Actually, most strings are repeated. 实际上,大多数字符串都是重复的。 And I have to find the unique ones and their repeat number. 而且我必须找到唯一的和重复的编号。

I use map: 我使用地图:

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

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

Do you have ideas how it could be done on fewer lines? 您有想法如何在更少的行上完成吗?

It could be done on one row: stringsMap[ currentString ]++; 可以在一行上完成: stringsMap[ currentString ]++; however short has indeterminate value by default. 但是short默认情况下具有不确定的值。

It could be done on one row: stringsMap[ currentString ]++; 可以在一行上完成:stringsMap [currentString] ++; however short has indeterminate value by default. 但是short默认情况下具有不确定的值。

This is not true, value is well defined as stated in 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. 如果执行插入操作,则将对映射的值进行值初始化(对于类类型,默认为默认构造, 否则为零初始化 ),并返回对其的引用。

emphasis is mine. 重点是我的。

So it is perfectly fine to write one liner: 因此,写一个衬纸是完全可以的:

stringsMap[ currentString ]++;

and this is common practice and even given as an example in the documentation: 这是常见的做法,甚至在文档中作为示例给出:

// 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. 但是short默认情况下具有不确定的值。

No. For a non existing key the map will use T() to initialize the value of the newly created entry, which effectively evaluates to 0 for unsigned short . 否。对于不存在的键,映射将使用T()初始化新创建的条目的值,对于unsigned short ,该条目的有效值为0

See the std::map::operator[] documentation (emphasis mine 1 ): 请参阅std::map::operator[]文档 (强调我的1 ):

1) Inserts value_type(key, T()) if the key does not exist. 1)如果键不存在value_type(key, T())插入value_type(key, T()) This function is equivalent to return insert(std::make_pair(key, T())).first->second; 此函数等效于return insert(std::make_pair(key, T())).first->second;
- key_type must meet the requirements of CopyConstructible . - key_type必须满足的要求, CopyConstructible
- mapped_type must meet the requirements of CopyConstructible and DefaultConstructible . mapped_type必须满足CopyConstructibleDefaultConstructible的要求。
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. 如果执行插入操作,则将对映射的值进行值初始化(对于类类型,默认为默认构造, 否则为零初始化 ),并返回对其的引用。

Thus, writing just 因此,只写

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

is perfectly fine. 很好。 The entire if block is redundant and not needed. 整个if块是多余的,不需要。


1) That's not really true, it was @Remy Lebau 's emphasis 1) 这不是真的,这是@Remy Lebau的重点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM