Zugriff auf C ++ const Map-Elemente

100

Ich habe versucht, mit dem Operator [] auf das Element in einer const C ++ - Zuordnung zuzugreifen, aber diese Methode ist fehlgeschlagen. Ich habe auch versucht, "at ()" zu verwenden, um dasselbe zu tun. Diesmal hat es funktioniert. Ich konnte jedoch keine Referenz zur Verwendung von "at ()" für den Zugriff auf Elemente in einer const C ++ - Zuordnung finden. Ist "at ()" eine neu hinzugefügte Funktion in der C ++ - Map? Wo finde ich mehr Infos dazu? Vielen Dank!

Ein Beispiel könnte das folgende sein:

#include <iostream>
#include <map>

using namespace std;

int main()
{
        map<int, char> A;
        A[1] = 'b';
        A[3] = 'c';

        const map<int, char> B = A;

        cout << B.at(3) << endl; // it works
        cout << B[3] << endl;  // it does not work

}

Bei Verwendung von "B [3]" wurden beim Kompilieren die folgenden Fehler zurückgegeben:

t01.cpp: 14: Fehler: Übergabe von 'const std :: map, std :: allocator >>' als 'dieses' Argument von '_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] ( const _Key &) [mit _Key = int, _Tp = char, _Compare = std :: less, _Alloc = std :: allocator>] 'verwirft Qualifizierer

Der verwendete Compiler ist g ++ 4.2.1

Eiskugel
quelle

Antworten:

124

at()ist eine neue Methode für std::mapin C ++ 11.

Anstatt ein neues standardmäßig erstelltes Element einzufügen, wie es der operator[]Fall ist, wenn ein Element mit dem angegebenen Schlüssel nicht vorhanden ist, wird eine std::out_of_rangeAusnahme ausgelöst . (Dies ähnelt dem Verhalten von at()für dequeund vector.)

Aufgrund dieses Verhaltens ist es sinnvoll, dass es zu einer constÜberlastung kommt at(), im Gegensatz dazu, operator[]die immer das Potenzial hat, die Karte zu ändern.

CB Bailey
quelle
Ist es möglich, dass "at" einen Standardwert zurückgibt, anstatt eine Ausnahme auszulösen?
user1202136
Ich verwende at()mit in VS2013 ein Projektset zur Verwendung des VS2010-Toolkits. Ich dachte, das bedeutet, dass ich C ++ 11 nicht benutze ... Aber es wird kompiliert ... ??
Thomthom
1
Ich muss nur kommentieren, dass es keinen Sinn macht, den const-Operator [] wegzulassen, der auch eine Ausnahme für ein nicht zugeordnetes Element auslösen könnte, anstatt die Karte zu ändern.
Spencer
@Spencer Es wäre überraschend, wenn die konstanten und nicht konstanten Überladungen von operator [] unterschiedliche Auswirkungen hätten. Normalerweise erwarten wir, dass sich das Programm, wenn einige Nicht-Const-Objekte oder Verweise in einem Programm zu Const gemacht werden, weiterhin auf die gleiche Weise verhält, solange es kompiliert wird. Wenn nur die nicht konstante Überladung Ausnahmen auslöst, kann dies zu Fehlern führen, die erst zur Laufzeit abgefangen werden.
Brian
@Brian Wolltest du sagen "Nur die const- Überladung darf Ausnahmen auslösen "?
Spencer
33

Wenn ein Element in a nicht vorhanden ist map, operator []wird es hinzugefügt - was in einer constMap offensichtlich nicht funktioniert, sodass C ++ keine constVersion des Operators definiert. Dies ist ein schönes Beispiel für die Typprüfung des Compilers, die einen möglichen Laufzeitfehler verhindert.

In Ihrem Fall müssen Sie findstattdessen ein Element verwenden, das nur dann ein (Iterator zum) Element zurückgibt, wenn es vorhanden ist. Das Element wird niemals geändert map. Wenn ein Element nicht vorhanden ist, gibt es einen Iterator an die Karte zurück end().

atexistiert nicht und sollte nicht einmal kompilieren. Vielleicht ist dies eine "Compiler-Erweiterung" (=ein Käfer neu in C ++ 0x).

Konrad Rudolph
quelle
Verbietet der C ++ - Standard der Implementierung, zusätzliche nicht standardmäßige Elementfunktionen in Bibliotheksklassen zu definieren?
Tim Martin
@ Tim Ich glaube, die Schnittstelle ist repariert, ja.
Konrad Rudolph
4

Der [] -Operator erstellt einen neuen Eintrag in der Karte, wenn der angegebene Schlüssel nicht vorhanden ist. Es kann somit die Karte ändern.

Siehe diesen Link .

vidstige
quelle