C ++ constマップ要素へのアクセス


100

operator []を使用してconst C ++マップの要素にアクセスしようとしましたが、このメソッドは失敗しました。また、 "at()"を使用して同じことを試みました。今回はうまくいきました。ただし、 "at()"を使用してconst C ++マップの要素にアクセスする方法についての参照は見つかりませんでした。「at()」はC ++マップに新しく追加された関数ですか?これに関する詳細情報はどこにありますか?どうもありがとうございました!

例は次のとおりです。

#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

}

「B [3]」を使用すると、コンパイル中に次のエラーが返されました。

t01.cpp:14:エラー: 'const std :: map、std :: allocator>>'を '_Tp&std :: map <_Key、_Tp、_Compare、_Alloc> :: operator []( const _Key&)[with _Key = int、_Tp = char、_Compare = std :: less、_Alloc = std :: allocator>] 'は修飾子を破棄します

使用されているコンパイラはg ++ 4.2.1です。

回答:


124

at()std::mapC ++ 11の新しいメソッドです。

指定さoperator[]れたキーを持つ要素が存在しない場合のように、新しいデフォルトの構成要素を挿入するのではなく、std::out_of_range例外をスローします。(これはat()for dequeおよびの動作に似ていますvector。)

この動作のため、のconstオーバーロードがあることは理にかなっています。これは常にマップを変更する可能性があるのat()とは異なりoperator[]ます。


例外をスローする代わりに、「at」でデフォルト値を返すことは可能ですか?
user1202136 2012

私が使用しているat()VS2010ツールキットを使用するために、プロジェクトのセットにVS2013でで。私はC ++ 11を使用していないことを意味すると思っていました...しかし、それでもコンパイルされます... ??
thomthom 2013

1
const operator []を省略しても意味がなく、マップを変更する代わりにマップされていない要素の例外をスローする可能性があることをコメントする必要があります。
スペンサー

@Spencer operator []のconstとnon-constのオーバーロードが異なる効果を持つとは、驚くべきことです。通常、プログラム内の一部の非constオブジェクトまたは参照がconstになった場合、プログラムはコンパイルされる限り、同じように動作し続けます。non-constオーバーロードのみに例外のスローを許可すると、実行時までキャッチされないバグが発生する可能性があります。
ブライアン

@ブライアン「constオーバーロードのみが例外をスローできるようにする」という意味ですか?
スペンサー

33

要素が存在しない場合はmapoperator []それを追加します-これは明らかでは動作しないことができるconstマップC ++で定義されていませんので、constオペレータのバージョンを。これは、潜在的なランタイムエラーを防ぐコンパイラのタイプチェッカーの良い例です。

あなたの場合、find代わりにを使用する必要があります。これは、存在する場合にのみ(要素のイテレータ)要素を返し、を変更することはありませんmap。アイテムが存在しない場合は、マップのにイテレータを返しますend()

at存在せず、コンパイルすらすべきではありません。おそらくこれは「コンパイラー拡張」(=バグ C ++ 0xの新機能)。


C ++標準では、実装がライブラリクラスで追加の非標準メンバー関数を定義することを禁止していますか?
ティムマーティン

@Timはい、インターフェースは固定されていると思います。
Konrad Rudolph

4

[]演算子は、指定されたキーが存在しない場合、マップに新しいエントリを作成します。したがって、マップが変更される場合があります。

このリンクを参照してください


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.