> would using an std::map give a performance gain over the above for loop?
Yes. Lookup, insertion and removal take O(log N) (logarithmic) time.
http://en.cppreference.com/w/cpp/container/map
With
std::string as the key type,
std::unordered_map would be very fast; on the average, lookup, insertion and removal take O(1) (constant) time.
http://en.cppreference.com/w/cpp/container/unordered_map
> is there any way to control the auto initialization of std::map data? For instance,
> if I do std::map < std::string, int >, trying to access a key value that doesn't exist
> should auto initialize the int to 0. I would like to say auto initialize it to -1 instead.
Yes; wrap it in a user-defined type with a custom default initialised value.
For example, for a mapped type that can appear as the type of a temple non-type parameter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
#include <iostream>
#include <unordered_map>
#include <string>
namespace detail
{
template < typename T, T DEFAULT_VALUE > struct init_wrapper
{
constexpr init_wrapper( T v = DEFAULT_VALUE ) noexcept : value(v) {}
operator T& () noexcept { return value ; }
constexpr operator T& () const noexcept { return value ; }
int* operator& () noexcept { return std::addressof(value) ; }
constexpr const int* operator& () const noexcept { return std::addressof(value) ; }
T value ;
};
}
template < typename KEY, typename VALUE, VALUE DEFAULT_VALUE >
using map_dv = std::unordered_map< KEY, detail::init_wrapper< VALUE, DEFAULT_VALUE > > ;
int main()
{
map_dv< std::string, int, -1 > my_map { {"abc",22}, {"xyz",17} } ;
std::cout << my_map["abc"] << ' ' << my_map["def"] << ' ' << my_map["xyz"] << '\n' ; // 22 -1 17
my_map["def"] = 99 ;
my_map.erase("xyz") ;
my_map["abc"] += 55 ;
std::cout << my_map["abc"] << ' ' << my_map["def"] << ' ' << my_map["xyz"] << '\n' ; // 77 99 -1
}
|
http://coliru.stacked-crooked.com/a/1e8316f13b874780
http://rextester.com/HWT35847
Note that if the mapped type is not a type that can appear as the type of a temple non-type parameter, the code for the wrapper would be quite a bit more involved.
If there are a large number of non-repeating spurious look ups, it would be cheaper to use the
find() member function.
http://en.cppreference.com/w/cpp/container/unordered_map/find