2016-04-13 1 views
1

ファイルを読み込み/解析し、キーと値のペアをマップに格納するクラスがあります。getter /によってコピーされないでアクセスされるマップの逆の反復

typedef std::map<std::string, const int> Data; 
typedef std::map<std::string, const int>::reverse_iterator DataItReverse; 

は今、私は、「パーサ」クラスinline Data getData() const {return _data;}

すべて私が問題になっているマップを反復処理を逆にするまでは素晴らしいですからデータを取得するためのゲッターを持っています。反復する上記

for(DataItReverse it_reverse = _parser->getData().rbegin(); 
    it_reverse != _parser->getData().rend(); 
    ++it_reverse) 
{ 
    std::cout << it_reverse->first << std::endl; 
} 

コード通常順(逆ではない)、私は一時変数にデータをコピーする場合、すべてがうまく機能して:

Data tmpData = _parser->getData(); 
for(...) 

私は以来、データのコピーを作成することを回避したいと思いますそれは大きな地図になるでしょう。


その内部にデータを複数回に

+0

は、あなたが作っている唯一の変更は、コピーされ、かつ秩序の逆転が何か他のものによるものではないことをことを* *絶対によろしいです。コピーが実際にオリジナルと同じデータ型であることも確かですか?そうでなければ、これはひどく奇妙に思えます。 – AaronI

+1

リファレンス「Data&getData();」を返すのはどうですか? – cwschmidt

+0

@AaronIはい私は確信している、私は**パディ**によって投稿された最初の答えを試してみるつもりだ、ちょうどこれを動作させる分を与える。 – Kyslik

答えて

1

をコピーされないよう_parserは、あなたが実際にあなたが使用した時間では存在しない一時的な反復処理を行うことにより、未定義の動作を取得しているポインタであることに注意してくださいイテレータ。

解決策として正しく識別されたとおりにコピーを作成するか、参照を返すように「ゲッター」を変更してください。

inline const Data & getData() const { return _data; } 

これは実際には標準的な方法です。データを派生していないか(クラスに格納されていない)、呼び出し後に変更されない限り、ゲッターから値で複雑な構造体を返すことは通常ありません(現在の状態を取得するためにロックを取得する必要があるマルチスレッド環境):

次に、const-iteratorsを使用する必要があります。

for(auto it = _parser->getData().rbegin(); it != _parser->getData().rend(); ++it) 

あなたがコピーを作成するか、また、非const「ゲッター」を提供する必要があると思います非constイテレータを使用するには:私は、ループ内で混乱を保存するためにautoキーワードを使用する傾向があります。これは一般的に推奨、多分あなたの目的に合っていない。

inline Data & getData() { return _data; } 
+0

** auto ** sを使用している間は、イテレータのタイプはまったく必要ですか? – Kyslik

+1

'auto'は呼び出しの型を推論します(ただし、C++ 0x以降でしか利用できません)。 constオブジェクトで 'rbegin'を呼び出すと' const_reverse_iterator'が返されるので、これが演繹型です。あなたの現在のアプローチを使用するのを止めることはありません。イテレータを 'const_reverse_iterator'にtypedefするだけです。 – paddy

+0

完璧な動作、非constバージョンを使用する場合、私は自分自身でconstバージョンを動作させる必要があります。ありがとうございました!私は(答えの最初の段落)_...存在しない一時的なものを反復することによって未定義の振る舞いについて考えなかった... _ – Kyslik

関連する問題