C++ (de)参考运算符的评估

C++ (de)参考运算符的评估,c++,pointers,c++11,evaluation,C++,Pointers,C++11,Evaluation,我有一个(未注释的…)源文件,我正试图理解它 static const Map *gCurMap; static std::vector<Map> mapVec; 我不明白&(*(I++)做什么。仅使用i++时它不会编译,但对我来说它看起来是一样的,因为我在“递增”i,然后我在给定地址请求值,然后我在请求该值的地址 一点也不&*x与operator&(operator*(x))相同,可以是您想要的任何内容 只有当指针类型如T*p时,&*p才与p相同。但是C++有用户定义的类型和可重

我有一个(未注释的…)源文件,我正试图理解它

static const Map *gCurMap;
static std::vector<Map> mapVec;

我不明白
&(*(I++)
做什么。仅使用
i++
时它不会编译,但对我来说它看起来是一样的,因为我在“递增”
i
,然后我在给定地址请求值,然后我在请求该值的地址

一点也不
&*x
operator&(operator*(x))
相同,可以是您想要的任何内容

只有当指针类型如
T*p
时,
&*p
才与
p
相同。但是C++有用户定义的类型和可重载的操作符。
解引用操作符(
*
)通常被重载,以便迭代器返回对容器元素的引用。符号和运算符(
&
)对容器元素的影响取决于类作者;如果希望无条件地获取地址,应使用
std::addressof(*i++)
(从您的fa-vou-rite头
)。

mapVec.begin()
返回一个迭代器,该迭代器具有重载的
运算符+
。迭代器的“取消引用”(重载的
运算符*
)用于访问
映射
对象。引用
&
是,因为
map
是一个指针,所以它被从
i
的解引用分配给对象的地址。我们不能简单地做
i++
,因为它仍然是一个迭代器,而不是实际的
map
对象。

i
是一个迭代器,
*i
是迭代器指向的对象,
&*i
是该对象的地址。如果迭代器只是一个普通的旧指针,这将是不必要的,但通常不是那么简单。迭代器通常属于某种类类型,它重载
运算符*
,以允许您访问它所指向的对象。这基本上是从迭代器到元素再到指向该元素的指针的转换


我会将增量移到下一行,因为它只会使给定的行更难理解。这是等效的,因为
i++
的值就是
i
,增量发生在之后。

它不一样:
i
是一个迭代器。取消对迭代器的引用会产生对某个对象的引用,即对某个类型的
T
T&
。获取这样一个对象的地址产生一个
T*
,即位于
i
位置的对象地址。迭代器也在同一个表达式中递增只是一个细节,可能是一个坏主意(增量后的效率通常低于增量前的效率,在代码摘录中不需要对迭代器进行增量后处理:它也可以在其他位置进行预增)

auto e = mapVec.end();
auto i = mapVec.begin();
while(i!=e) {
    // ...
    const Map *map = gCurMap = &(*(i++));
    // ...
}