std:: wartość domyślna mapy
Czy istnieje sposób, aby określić wartość domyślną std::map
's operator[]
zwraca, gdy klucz nie istnieje?
9 answers
Nie, Nie ma. najprostszym rozwiązaniem jest napisanie w tym celu własnej funkcji darmowego szablonu. Coś w stylu:
#include <string>
#include <map>
using namespace std;
template <typename K, typename V>
V GetWithDef(const std::map <K,V> & m, const K & key, const V & defval ) {
typename std::map<K,V>::const_iterator it = m.find( key );
if ( it == m.end() ) {
return defval;
}
else {
return it->second;
}
}
int main() {
map <string,int> x;
...
int i = GetWithDef( x, string("foo"), 42 );
}
C++11 Update
Przeznaczenie: uwzględnianie ogólnych kontenerów asocjacyjnych, a także opcjonalnych parametrów komparatora i alokatora.
template <template<class,class,class...> class C, typename K, typename V, typename... Args>
V GetWithDef(const C<K,V,Args...>& m, K const& key, const V & defval)
{
typename C<K,V,Args...>::const_iterator it = m.find( key );
if (it == m.end())
return defval;
return it->second;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-05 15:49:00
Chociaż to nie do końca odpowiada na pytanie, obejrzałem problem z takim kodem:
struct IntDefaultedToMinusOne
{
int i = -1;
};
std::map<std::string, IntDefaultedToMinusOne > mymap;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-11 08:32:59
Standard C++ (23.3.1.2) określa, że nowo wstawiona wartość jest domyślnie skonstruowana, więc sama map
nie zapewnia sposobu na to. Twoje wybory to:
- nadaj typowi wartości domyślny konstruktor, który inicjalizuje go na żądaną wartość, lub
- zawiń mapę w swoją własną klasę, która dostarcza domyślną wartość i implementuje
operator[]
, Aby wstawić tę domyślną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 12:07:42
template<typename T, T X>
struct Default {
Default () : val(T(X)) {}
Default (T const & val) : val(val) {}
operator T & () { return val; }
operator T const & () const { return val; }
T val;
};
<...>
std::map<KeyType, Default<ValueType, DefaultValue> > mapping;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-08 17:49:00
Bardziej ogólna wersja, Obsługa C++98/03 i więcej kontenerów
Działa z ogólnymi kontenerami asocjacyjnymi, jedynym parametrem szablonu jest sam typ kontenera.
Obsługiwane kontenery: std::map
, std::multimap
, std::unordered_map
, std::unordered_multimap
, wxHashMap
, QMap
, QMultiMap
, QHash
, QMultiHash
, itd.
template<typename MAP>
const typename MAP::mapped_type& get_with_default(const MAP& m,
const typename MAP::key_type& key,
const typename MAP::mapped_type& defval)
{
typename MAP::const_iterator it = m.find(key);
if (it == m.end())
return defval;
return it->second;
}
Użycie:
std::map<int, std::string> t;
t[1] = "one";
string s = get_with_default(t, 2, "unknown");
Tutaj jest podobna implementacja przy użyciu klasy wrapper, która jest bardziej podobna do metody get()
typu dict
w Pythonie: https://github.com/hltj/wxMEdit/blob/master/src/xm/xm_utils.hpp
template<typename MAP>
struct map_wrapper
{
typedef typename MAP::key_type K;
typedef typename MAP::mapped_type V;
typedef typename MAP::const_iterator CIT;
map_wrapper(const MAP& m) :m_map(m) {}
const V& get(const K& key, const V& default_val) const
{
CIT it = m_map.find(key);
if (it == m_map.end())
return default_val;
return it->second;
}
private:
const MAP& m_map;
};
template<typename MAP>
map_wrapper<MAP> wrap_map(const MAP& m)
{
return map_wrapper<MAP>(m);
}
Użycie:
std::map<int, std::string> t;
t[1] = "one";
string s = wrap_map(t).get(2, "unknown");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-19 17:21:47
Nie można określić wartości domyślnej - jest to zawsze wartość konstruowana przez konstruktor default (parametr zerowy).
W rzeczywistości operator[]
prawdopodobnie robi więcej, niż się spodziewasz, ponieważ jeśli wartość nie istnieje dla danego klucza na mapie, wstawia nowy z wartością z domyślnego konstruktora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-25 17:46:59
C++17 dostarcza try_emplace
, co robi dokładnie to. Pobiera klucz i listę argumentów dla konstruktora wartości i zwraca parę: an iterator
i a bool
.: http://en.cppreference.com/w/cpp/container/map/try_emplace
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-10 17:22:32
Wartość jest inicjalizowana przy użyciu domyślnego konstruktora, jak mówią inne odpowiedzi. Warto jednak dodać, że w przypadku typów prostych (typów całkowych, takich jak typy int, float, pointer lub POD (plan old data)), wartości są inicjalizowane zerem (lub zerowane przez inicjalizację wartości (co w praktyce jest tym samym), w zależności od tego, która wersja C++ jest używana).
W każdym razie, dolna linia jest taka, że mapy z prostymi typami automatycznie zerują nowe elementy. Więc w niektórych przypadki, nie ma potrzeby martwić się o jawne podanie domyślnej wartości początkowej.
std::map<int, char*> map;
typedef char *P;
char *p = map[123],
*p1 = P(); // map uses the same construct inside, causes zero-initialization
assert(!p && !p1); // both will be 0
Zobacz czy nawiasy po nazwie typu różnią się od new?Po więcej szczegółów w tej sprawie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:30
Może możesz dać Niestandardowy alokator, który przydziela z domyślną wartością, którą chcesz.
template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 12:06:45