【问题标题】:Evaluation of (de)reference operators评估(去)引用运算符
【发布时间】:2012-12-18 22:49:17
【问题描述】:

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

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++));
    // ...
}

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

【问题讨论】:

    标签: c++ pointers c++11 evaluation


    【解决方案1】:

    一点也不。 &amp;*xoperator&amp;(operator*(x)) 相同,可以是任何你想要的。

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

    解引用运算符 (*) 通常被重载以供迭代器返回对容器元素的引用。与号运算符 (&amp;) 对容器元素的影响取决于类作者;如果你想无条件获取地址,你应该使用std::addressof(*i++)(来自你最喜欢的header&lt;memory&gt;)。

    【讨论】:

      【解决方案2】:

      mapVec.begin() 返回一个迭代器,它有一个重载的operator++。迭代器的“解引用”(重载operator*)是为了获取map 对象。引用&amp; 是,因为map 是一个指针,所以它被分配给来自i 的取消引用的对象的地址。我们不能简单地做i++,因为它仍然是一个迭代器,而不是实际的map 对象。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-02
            • 1970-01-01
            • 2018-12-15
            相关资源
            最近更新 更多