マップ内にマップを作成しようとしています:
typedef map<float,mytype> inner_map;
typedef map<float,inner_map> outer_map;
内部マップ内に何かを入れることはできますか、それともiterator :: secondはコピーを返しますか?
stl_pair.hは後者を示唆しています:
74: _T2 second; ///< @c second is a copy of the second object
しかし、私のテストプログラムは、次のようなコードで正常に実行されます。
it = my_map.lower_bound(3.1415);
(*it).second.insert(inner_map::value_type(2.71828,"Hello world!");
では、真実はどこにあるのでしょうか。これはコピーですか?
stl_pair.h
のコメントは、この特定のケースでは誤解を招く可能性があります。
map::iterator
は実際にはマップ内の元のデータを参照しているため、noコピーがあります(value_type
、それ自体はpair
)、それはコピーではありません。したがって、iterator::second
は元のデータも参照します。
C++ 11イテレータを使用している人のために、この質問に対するフォローアップの回答を追加したいと思います...
次のコード:
std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (auto i : m)
{
std::cout << i.first << ": " << i.second << std::endl;
}
does "auto"はデフォルトで値であり、const参照ではないため、キーと値をコピーします(少なくとも、clang 3.1の動作はこのようになります)。
さらに、コード:
std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (const std::pair<std::string,std:string>& i : m)
{
std::cout << i.first << ": " << i.second << std::endl;
}
また正しいコードは次のようになるため、キーと値をコピーします。
std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (const auto& i : m)
{
std::cout << i.first << ": " << i.second << std::endl;
}
または
std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (const std::pair<const std::string,std:string>& i : m)
{
std::cout << i.first << ": " << i.second << std::endl;
}
value_type
マップはペアであるため、最初と2番目のメンバーがあります。すべてのイテレータと同様に、マップイテレータは疑似ポインタです。つまり、コレクション内のデータを指し、そのデータのコピーを指しません。
イテレータは再割り当て可能であり(つまり、イテレータを使用するため)、他のオブジェクトを参照するために参照を再割り当てできないため、内部的には参照ではなくポインタが含まれることはほぼ確実です。
Const_iteratorがあり、その下の型がPODである場合でも、誰かがこれを行う場合に備えて、それへのポインターが必要です。
map< int, int > m;
m.insert( make_pair( 1, 2 );
map<int,int>::const_iterator citer = m.begin();
map<int,int>::iterator iter = m.begin();
iter->second = 3;
std::cout << citer->second << '\n'; // should always print 3
動作を定義し、3を出力する必要があります。これは、const_iteratorがconstであり、intのみである後に「最適化」することを決定した場合には発生しません。
イテレータは、参照が解除されると、 参照を提供します 。