4 Stimmen

Wie aktiviere ich geschweifte Initialisierungslisten für meine eigene Sammlungsklasse?

Bei diesem Beispiel:

template
class BeispielContainer
{
private:        
  std::map _objects;
  int _sum;

public:
  BeispielContainer()
    : _objects(), _sum(0)
  {
  }

  void Add(T obj, int add)
  {
    _objects[obj] = add; // ja, das ist schlecht, aber es ist ein Beispiel.
    _sum += add;
  }
};

Was ist erforderlich, um es wie folgt verwenden zu können:

BeispielContainer _raritaeten =
{
  { "Eins", 600 },
  { "Zwei", 200 },
  { "Drei", 50 },
  { "Vier", 10 },
  { "Fuenf", 1 },
};

Ich weiß, dass es irgendwie möglich sein muss, weil ich bereits eine std::map so initialisieren kann.

Vielen Dank im Voraus für jede Antwort.

11voto

Andy Prowl Punkte 119432

Fügen Sie einfach einen Konstruktor hinzu, der ein std::initializer_list akzeptiert, zu Ihrer ExampleContainer-Klasse:

ExampleContainer(std::initializer_list::value_type> l)
    :
    _objects(l)
{
}

Dies wird jedes Mal aufgerufen, wenn Sie geschweifte Klammern verwenden, um das Objekt zu initialisieren, wie in diesem Fall:

ExampleContainer _rarities =
{
    ...
};

Auf diese Weise wird jedes Element innerhalb der geschweiften Klammern ein Element der Initialisierungsliste.

Da der zugrunde liegende Typ der Initialisierungsliste hier std::map::value_type ist, werden temporäre Objekte dieses Typs aus den von Ihnen bereitgestellten Werten erstellt:

ExampleContainer _rarities =
{
    { "One", 600 },     // Jeder dieser Einträge führt zur Erstellung eines
    { "Two", 200 },     // temporären Objekts vom Typ:
    { "Three", 50 },    //     std::pair
    { "Four", 10 },     // das ein Element der Initialisierungsliste des Konstruktors wird.
    { "Five", 1 },      
};

Beachten Sie auch, dass die Konvertierung von einem Zeichenfolgenliteral zu char* in C++03 veraltet ist und in C++11 ungültig ist (Zeichenfolgenliterale haben in C++11 den Typ char const[]). Daher sollten Sie Ihrem Variablentyp _rarities möglicherweise den Typ ExampleContainer geben (C-Array-Typen zerfallen zu Zeiger-Typen).

UPDATE:

Wie von @LightnessRacesInOrbit in den Kommentaren korrekt festgestellt wurde, ist dieser Ansatz gefährlich, wenn Sie in Ihrem Container nicht nur Zeichenfolgenliterale verwenden werden (das ist etwas, was ich von Ihrem Beispiel angenommen habe, aber in der Tat nichts darauf hindeutet). Es ist eine bessere Idee, stattdessen std::string zu verwenden (Sie sollten daher _rarities als ExampleContainer deklarieren).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X