首页 > 解决方案 > Eclipse CDT:无法解析 foreach 循环中的“开始”和“结束”符号

问题描述

每当我想直接迭代函数返回的数据时,eclipse CDT 的索引器无法正确识别 foreach 循环中所需的“结束”和“开始”符号。当我第一次将结果放入临时变量时,它就起作用了。

MWE:

#include "mwe.h"

int main(int argc, char **argv) {
    auto tmp = do_something();
    for(auto &x : tmp){ } //Working
    for(auto &x : do_something()){ } //Symbol 'end'/'begin' could not be resolved
}

mwe.h:

#include<iterator>

class X { };
class Handle { };
class MyIterator: public std::iterator<X, std::input_iterator_tag> {
public:
    explicit MyIterator(Handle &iter) : iter_(&iter) { }
    MyIterator() { }
    MyIterator &operator++() { return *this; }
    MyIterator operator++(int) { return *this;  }
    X &operator*() { return x;  }
    X *operator->() { return &**this; }
    friend bool operator==(MyIterator a, MyIterator b) { return true; }
    friend bool operator!=(MyIterator a, MyIterator b) { return false; }
private:
    Handle *iter_;
    X x;
};

inline MyIterator begin(Handle &it) { return MyIterator(it); }
inline MyIterator end(Handle &) { return MyIterator(); }

Handle do_something() { return Handle(); }

代码编译并且没有错误,只有索引器告诉我它没有找到符号。也就是说,解决问题并不是真正必要的,但它很烦人。

附加说明:我已经检查了许多其他关于 CDT 索引器的问题,但答案并没有解决我的问题:

Eclipse CDT Indexer 不能完全识别 c++11

Eclipse CDT:无法解析符号“cout”

https://www.eclipse.org/forums/index.php/t/636348/

代码有问题还是 CDT 中的(已知)错误?

标签: c++11foreacheclipse-cdt

解决方案


如果我们看一下定义begin

inline MyIterator begin(Handle &it) { return MyIterator(it); }

我们看到它引用了一个非常量对象。这意味着您不能将临时对象传递给函数。就像直接使用时会发生什么do_something()。快速的解决方案是添加一个采用右值引用的重载:

inline MyIterator begin(Handle &&it) { return MyIterator(it); }
//                             ^^
//     Note double ampersand here

但是,您的代码还有其他可能的缺陷,特别是因为do_something按值返回。这意味着每次调用都do_something将返回一个单独的对象,如果do_something多次调用,您将拥有具有不同数据的不同对象。

另请注意,std::iterator在 C++17 标准中已弃用。std::iterator_traits如果您想要通用类型,则应该专门化。


推荐阅读