Обтекание std::vector<bool>
Вы можете обернуть std::vector<bool>
, который хотите инициализировать, следующим образом:
template<size_t N>
struct myvector {
myvector(): data(N) {}
std::vector<bool> data;
};
Затем объявите mymap
как карту, значение которойтип относится к этому типу оболочки myvector<N>
вместо std::vector<bool>
.Например, для N
, равного 100
:
std::map<int, myvector<100>> mymap;
Если ключ 42
еще не существует на карте, то:
auto& newvec = mymap[42];
создастэкземпляр типа myvector<100>
, который по очереди инициализирует std::vector<bool>
размера 100
.
Вы можете получить доступ к созданному объекту std::vector<bool>
либо через data
элемент данных myvector
, либо выполнив reinterpret_cast<std::vector<bool>&>(newvec)
.
Используя std::map::find()
и std::map::emplace()
Другой подход заключается в использовании std::map::find()
вместо std::map::operator[]()
, чтобы сначала выяснить, существует ли данный ключ на карте, сравнивая его возвращенный итератор с возвращенным std::map::end()
.Если данный ключ не существует, то построить вектор, используя std::map::emplace()
.
В вашем примере newvec
можно инициализировать для этого подхода с помощью троичного оператора :
auto it = mymap.find(42); // search for an element with the key 42
bool is_key_in_map = it != mymap.end();
// if the element with the given key exists, then return it, otherwise
// construct it
auto& newvec = is_key_in_map? it->second:
mymap.emplace(42, std::vector<bool>(100, true)).first->second;
На самом деле, вы можете напрямую позвонить std::map::emplace()
без проверки, существует ли данный ключ, но это будет стоить бесполезного создания временного объекта (т.е. std::vector<bool>
объекта), если ключ уже присутствует на карте:
auto& newvec = mymap.emplace(42, std::vector<bool>(100, true)).first->second;
Начиная с C ++ 17: std::map::try_emplace()
Вы можете использовать std::map::try_emplace()
вместо std::map::emplace()
:
auto& newvec = mymap.try_emplace(42, 100, true).first->second;
Таким образом, временный объект, std::vector<bool>(100, true)
, не будет построено, если карта уже содержит данный ключ (т. Е. Если она уже содержит ключ 42
).Следовательно, это более эффективно, чем использование std::map::emplace()
, поскольку никакой временный объект не будет создан, если в этом нет необходимости.Тем не менее, он требует C ++ 17.