Re: Initializing a map...
red floyd wrote:
Jeff Schwab wrote:
Sam wrote:
barcaroller writes:
Is there a way in C++ to initialize an STL map in one statement (the
way arrays can be initialized in C)?
For example, instead of using:
map<type1,type2> mymap;
mymap[key1] = value1;
mymap[key2] = value2;
I would like to use something like:
// wrong syntax!
map<type1,type2> mymap = { (key1, value1), (key2, value2) };
You can subclass it, and define an operator function.
template<typename keyType, typename valType> class myMap
: public std::map<keyType, valType> {
public:
myMap<keyType, valType> &operator()(keyType k, valType v)
{
(*this)[k]=v;
return *this;
};
};
You can initialize these objects as follows:
myMap<int, int> z=myMap<int, int>()(3, 4)(5, 6);
.. and so on. You can use these objects anywhere std::map is acceptable.
....
Or you could use a proxy initializer:
#include <map>
template<typename K, typename V>
class map_initializer_proxy
{
std::map<K, V> map_;
public:
map_initializer_proxy(const K& k, const V& v)
{
map_[k] = v;
}
map_initializer_proxy& operator()(const K& k, const V& v)
{
map_[k] = v;
return *this;
}
operator const std::map<K,V>&() const
{
return map_;
}
};
template<typename K, typename V>
map_initializer_proxy<K,V> map_initializer(const K& k, const V& v)
{
return map_initializer_proxy<K,V>(k,v);
}
#include <iostream>
#include <ostream>
int main()
{
std::map<int, int> m(map_initializer(3,4)(5,6)(7,8));
....
return 0;
}
That's a neat idea. It could probably be made a little more efficient
by replacing the calls to map::operator[] with calls to map::find and
map::insert. If the OP is willing to have two statements rather than
one, a copy of the map's data can also be saved by adding a swap function:
template<typename K, typename V>
struct map_initializer_proxy {
// ...
void swap(std::map<K, V>& m) {
map_.swap(m);
}
};
int main() {
std::map<int, int> m;
map_initializer(3,4)(5,6)(7,8).swap(m);
}
This is admittedly not as nifty, since it's not really an
initialization. It's more like a map_filler.