简体   繁体   中英

Increment int in an unordered_map?

int c = counts.at(v).at(id);
std::cout << c;
counts.at(v).emplace(id,c+1);
std::cout << counts.at(v).at(id);

counts is an unordered_map of unordered_map. The first cout prints 1, the second prints 1, why it is not incremented ?

emplace does not insert anything if that key already exists, so instead you could use the following

counts.at(v)[id] += 1;

The operator[] will either default construct a value if that key does not exist, or will return a modify-able reference if it does exist

You've already found how to get to the element in question:

counts.at(v).at(id);

Per documentation , this is a reference (until you copy it into a new object, like c ), so you can simply increment it:

counts.at(v).at(id)++;

Or, if we're assuming both keys already exist (or you don't mind them being created if they don't), as they do in your code:

counts[v][id]++;

… which, in my opinion, is much easier to read.

The emplace function is for creating a new element where none previously existed.


In totality, then:

std::cout << counts[v][id] << ' ';
counts[v][id]++;
std::cout << counts[v][id];

Or, if you don't want the repeated lookups:

auto& elm = counts[v][id];
std::cout << elm << ' ';
elm++;
std::cout << elm;

You could even shorten it further (though this is less clear):

auto& elm = counts[v][id];
std::cout << elm++ << ' ';
std::cout << elm;

Or, since C++17 :

auto& elm = counts[v][id];
std::cout << elm++ << ' ' << elm;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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