次の 2 行の C++ コードの場合
map<string, vector<size_t> >::iterator beg = mapper.begin();
vector<size_t>& indics = (*beg).second;
彼らが何を達成したいのか、具体的には、コードの 2 行目の&
andは何を意味するのかを理解するにはどうすればよいでしょうか?*
map<string, vector<size_t> >::iterator beg = mapper.begin();
からにmap
マップするがあります。に従って、マップ内の最初の要素を取得します。これは、キー値が小さい要素になります。string
vector<size_t>
iterator
std::less<string>
vector<size_t>& indics = (*beg).second;
または同じものは何ですか
vector<size_t>& indics = beg->second;
キーと値のペアの 2 番目の値を取得vector<size_t>
します。つまり、マップの最初の要素のを取得します。それへの非 const 参照を保持しているので、その値を変更できます。
map<string, vector<size_t> >::iterator beg = mapper.begin();
文字列からベクターへのマップの先頭に反復子を宣言しています。
vector<size_t>& indics = (*beg).second;
おそらくいくつかのインデックスを変更する目的で、反復子 (*beg) を逆参照した後、ペアの 2 番目のメンバーであるベクトルへの参照 (&) を宣言しています。
イテレータは、STL コンテナの大きな部分を占めています。それらに慣れていない場合は、良い本を手に入れるか、C++ STL チュートリアルをグーグルで検索することをお勧めします。
beg
は a のイテレータでありmap
、(構文的にはポインタのように) 逆参照pair
してフィールドfirst
を持つ a を取得second
し、キー (a string
) と値 ( のvector
a ) に対応することができますsize_t
。
So*beg
はペアを(*beg).second
参照し、ベクトルへの参照を提供します。これはローカル変数に格納されますindics
。(もちろん、これを書いた方がきれいbeg->second
です。)
&
indics の型宣言の は、変数が参照であることを意味します。ベクトルはコピーされません。indics は、マップに格納されたベクトルのローカルな「名前」になります。
最初に C を学習することをお勧めします。これは非常に単純な言語であり、C の基礎ができたら C++ の学習を開始します。
あなたの質問は実際にはマップクラスとは何の関係もありません。
// this is a number.
int foo = 5;
// this is a pointer to foo. You can use this to refer to any thing of type "int"
int* pFoo = &foo;
// now you are getting the number back from the pointer. This creates a copy
// of foo. If you change bar, foo will not change.
int bar = *pFoo;
// this is a reference to foo. E.g. another way of talking about foo. If you change
// foo2, foo will also change.
int& foo2 = *pFoo;
「(*beg).second;」について詳しく説明したいと思います。
beg はポインターとして扱われますが、そのように宣言されていないため、これは紛らわしい部分だと思います。さらに、イテレータ クラスで宣言されていないため、「秒」がどこから来たのか明確でない場合があります。
beg は、 * 演算子がオーバーライドされた型 iterator の単なる通常のオブジェクトであることを認識しておく必要があります。したがって、「*beg」を実行すると、ポインターを使用しようとするのではなく、メソッドが呼び出されます。
現在、反復子クラスの * 演算子の実装は、ポインターのように現在の要素を返します。そのため、最初は混乱するかもしれませんが、より明確にするために * 演算子が使用されます。
たとえば、.h ファイルの反復子の宣言を見てください。
template <class BidirectionalIterator, class T, __DFL_TMPL_PARAM(Reference, T& ),
__DFL_TYPE_PARAM(Distance, ptrdiff_t)>
# endif
class reverse_bidirectional_iterator {
typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference__,
Distance> self;
friend inline bool operator==(const self& x, const self& y);
protected:
BidirectionalIterator current;
public:
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
# if defined (__STL_MSVC50_COMPATIBILITY)
typedef Pointer pointer;
# else
typedef T* pointer;
# endif
typedef Reference reference;
reverse_bidirectional_iterator() {}
explicit reverse_bidirectional_iterator(const BidirectionalIterator& x)
: current(x) {}
BidirectionalIterator base() const { return current; }
Reference operator*() const {
BidirectionalIterator tmp = current;
return *--tmp;
}
末尾の * 演算子の宣言に注意してください。
したがって、* はマップ要素を返します。マップ要素は常に、宣言された「2 番目の」要素を持つ「構造体ペア」型です。繰り返しますが、ペアの .h ファイルを確認してください。
template <class T1, class T2>
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
...
したがって、( *beg ).second への呼び出しは、マップの反復子の * 演算子を実行しています。マップは一連の「ペア」であり、ペアは 1 番目と 2 番目の要素を持つ構造体です。この場合、インデックス付き要素「second」を取得しています。この場合、これはベクトルです。
一方、次の & は通常の参照であるため、コピーではなくベクトルへの参照を取得するため、マップ内の値を変更できます。
それが理にかなっていることを願っています。
-アレハンドロ