(取消)引用运算符的评估

Evaluation of (de)reference operators

本文关键字:评估 运算符 引用 取消      更新时间:2023-10-16

我有一个(未注释的...)源文件,我正在努力理解。

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

然后

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

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

完全没有。 &*xoperator&(operator*(x)) 相同,可以是您想要的任何内容。

仅对于像T * p这样的指针类型&*pp相同,才是正确的。但C++具有用户定义的类型和可重载的运算符。

取消引用运算符(*)通常是重载的,以便迭代器返回对容器元素的引用。与号运算符(&)对容器元素的影响取决于类作者;如果你想无条件地获取地址,你应该使用std::addressof(*i++)(从你最喜欢的标题<memory>)。

mapVec.begin() 返回一个具有重载operator++的迭代器。迭代器的"取消引用"(重载operator*)是到达map对象。引用&是,嗯,因为map是一个指针,所以它被分配给对象的地址,从i的取消引用。我们不能简单地做i++因为它仍然是一个迭代器,而不是实际的map对象。

i是一个

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

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

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