对于以下两行 C++ 代码
map<string, vector<size_t> >::iterator beg = mapper.begin();
vector<size_t>& indics = (*beg).second;
如何理解他们想要实现什么,具体来说,第二行代码中的 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;
我们得到键值对中的第二个值,即我们得到vector<size_t>
映射中第一个元素的值。我们保留对它的非常量引用,因此我们可以修改它的值。
map<string, vector<size_t> >::iterator beg = mapper.begin();
将迭代器声明到字符串到向量的映射的开头。
vector<size_t>& indics = (*beg).second;
在取消引用迭代器 (*beg) 之后,声明对向量的引用 (&),该向量是该对的第二个成员,可能是为了更改某些索引。
迭代器是 STL 容器的重要组成部分。如果您不熟悉它们,我建议您选择一本好书或在谷歌上搜索 C++ STL 教程。
beg
是 a 的迭代器map
,您可以取消引用它(在语法上,就像指针一样)以获取pair
带有字段first
并second
对应于键 (a string
) 和值 (a vector
of size_t
's) 的 a。
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 只是一个普通的迭代器类型对象,它的 * 运算符已被覆盖。因此,当您执行“* 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;
}
请注意末尾 * 运算符的声明。
所以 * 正在返回一个地图元素。地图元素始终是“结构对”类型,它声明了“第二个”元素。同样,只需检查该对的 .h 文件:
template <class T1, class T2>
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
...
因此,对 ( *beg ).second 的调用正在执行映射的迭代器的 * 运算符,映射是一系列“对”,而对是具有第一个和第二个元素的结构。在这种情况下,我们得到索引元素“second”,在这种情况下,它是一个向量。
另一方面,下面的 & 是常规引用,因此您获得的是对向量的引用,而不是副本,因此您可以更改地图中的值。
我希望这是有道理的。
-亚历杭德罗