Wie kann man eine statische Karte richtig initialisieren? Brauchen wir eine statische Funktion, die sie initialisiert?
Antworten
Zu viele Anzeigen?C++11 verwenden:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Verwendung von Boost.Zuweisen :
#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;
map<int, char> m = map_list_of (1, 'a') (3, 'b') (5, 'c') (7, 'd');
Es ist gar nicht so schwierig, etwas Ähnliches wie Boost zu machen. Hier ist eine Klasse mit nur drei Funktionen, einschließlich des Konstruktors, um zu replizieren, was boost (fast) getan hat.
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(const T& key, const U& val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U& val)
{
m_map[key] = val;
return *this;
}
operator std::map<T, U>()
{
return m_map;
}
};
Verwendung:
std::map mymap = create\_map<int, int >(1,2)(3,4)(5,6);
Der obige Code eignet sich am besten für die Initialisierung globaler Variablen oder statischer Mitglieder einer Klasse, die initialisiert werden muss und von der man nicht weiß, wann sie zum ersten Mal verwendet wird, aber man möchte sicherstellen, dass die Werte darin verfügbar sind.
Wenn Sie z.B. Elemente in eine bestehende std::map einfügen müssen... hier ist eine weitere Klasse für Sie.
template <typename MapType>
class map_add_values {
private:
MapType mMap;
public:
typedef typename MapType::key_type KeyType;
typedef typename MapType::mapped_type MappedType;
map_add_values(const KeyType& key, const MappedType& val)
{
mMap[key] = val;
}
map_add_values& operator()(const KeyType& key, const MappedType& val) {
mMap[key] = val;
return *this;
}
void to (MapType& map) {
map.insert(mMap.begin(), mMap.end());
}
};
Verwendung:
typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);
Sehen Sie es in Aktion mit GCC 4.7.2 hier: http://ideone.com/3uYJiH
############### ALLES DARUNTER IST VERALTET #################
EDIT : Die map_add_values
Klasse unten, die die ursprüngliche Lösung, die ich vorgeschlagen hatte, würde fehlschlagen, wenn es zu GCC 4.5+ kommt. Bitte sehen Sie sich den Code oben an, um zu erfahren, wie man hinzufügen. Werte zur bestehenden Karte.
template<typename T, typename U>
class map_add_values
{
private:
std::map<T,U>& m_map;
public:
map_add_values(std::map<T, U>& _map):m_map(_map){}
map_add_values& operator()(const T& _key, const U& _val)
{
m_map[key] = val;
return *this;
}
};
Verwendung:
std::map<int, int> my\_map;
// Later somewhere along the code
map\_add\_values<int,int>(my\_map)(1,2)(3,4)(5,6);
HINWEIS: Zuvor habe ich eine operator []
für die Addition der tatsächlichen Werte. Dies ist, wie von dalle kommentiert, nicht möglich.
##################### ENDE DES ÜBERHOLTEN ABSCHNITTS #####################
Hier ist eine weitere Möglichkeit, die den 2-Elemente-Datenkonstruktor verwendet. Es werden keine Funktionen zur Initialisierung benötigt. Es gibt keinen Code von Drittanbietern (Boost), keine statischen Funktionen oder Objekte, keine Tricks, nur einfaches C++:
#include <map>
#include <string>
typedef std::map<std::string, int> MyMap;
const MyMap::value_type rawData[] = {
MyMap::value_type("hello", 42),
MyMap::value_type("world", 88),
};
const int numElems = sizeof rawData / sizeof rawData[0];
MyMap myMap(rawData, rawData + numElems);
Seit ich diese Antwort geschrieben habe, ist C++11 erschienen. Sie können jetzt STL-Container direkt initialisieren, indem Sie die neue Funktion der Initialisierungsliste verwenden:
const MyMap myMap = { {"hello", 42}, {"world", 88} };
Zum Beispiel:
const std::map<LogLevel, const char*> g_log_levels_dsc =
{
{ LogLevel::Disabled, "[---]" },
{ LogLevel::Info, "[inf]" },
{ LogLevel::Warning, "[wrn]" },
{ LogLevel::Error, "[err]" },
{ LogLevel::Debug, "[dbg]" }
};
Wenn map ein Datenelement einer Klasse ist, können Sie es direkt im Header auf folgende Weise initialisieren (seit C++17):
// Example
template<>
class StringConverter<CacheMode> final
{
public:
static auto convert(CacheMode mode) -> const std::string&
{
// validate...
return s_modes.at(mode);
}
private:
static inline const std::map<CacheMode, std::string> s_modes =
{
{ CacheMode::All, "All" },
{ CacheMode::Selective, "Selective" },
{ CacheMode::None, "None" }
// etc
};
};
- See previous answers
- Weitere Antworten anzeigen