Wrapping the std::vector<bool>
You could wrap the std::vector<bool>
you want to initialise in the following way:
template<size_t N>
struct myvector {
myvector(): data(N) {}
std::vector<bool> data;
};
Then, declare mymap
as a map whose value type is of this wrapper type, myvector<N>
, instead of std::vector<bool>
. For example, for N
equal to 100
:
std::map<int, myvector<100>> mymap;
If the key 42
does not exist in the map yet, then:
auto& newvec = mymap[42];
will create an instance of type myvector<100>
, which in turns, initialises an std::vector<bool>
of size 100
.
You could access the created std::vector<bool>
object either through myvector
's data
data member or by performing reinterpret_cast<std::vector<bool>&>(newvec)
.
Using std::map::find()
and std::map::emplace()
Another approach would be to use std::map::find()
instead of std::map::operator[]()
to first find out whether a given key already exists in the map by comparing its returned iterator against the one returned by std::map::end()
. If the given key does not exist, then construct the vector using std::map::emplace()
.
In your example, the newvec
could be initialized for this approach by means of the ternary opererator:
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;
Actually, you can directly call std::map::emplace()
without checking whether the given key already exists, but that will cost the useless creation of a temporary object (i.e., the std::vector<bool>
object) if the key is already present in the map:
auto& newvec = mymap.emplace(42, std::vector<bool>(100, true)).first->second;
Since C++17: std::map::try_emplace()
You could use std::map::try_emplace()
instead of std::map::emplace()
:
auto& newvec = mymap.try_emplace(42, 100, true).first->second;
This way, the temporary object, std::vector<bool>(100, true)
, won't be constructed if the map already contains the given key (i.e., if it already contains the key 42
). This is, therefore, more efficient than using std::map::emplace()
, since no temporary object will be constructed if not necessary. However, it does require C++17.