c++11 - 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
https://www.eclipse.org/forums/index.php/t/636348/
代码有问题还是 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
如果您想要通用类型,则应该专门化。
推荐阅读
- javascript - 当我在数字旁边添加一个 var 时,我的代码给了我一个 NaN 值
- arrays - 为什么 MAXLOC 不尊重数组边界?
- jenkins - 如果它是新分支的第一次运行,你能从 Jenkins 管道内部识别吗?
- windows - 送钥匙win+E
- java - spring事务超时可配置
- mysql - 如何查找相似的数据库查询
- css - 为什么我的字体大小百分比在 CSS 中不起作用?
- python - 为什么 pylint 在函数之外需要大写的变量名?
- node.js - 根据从基于 pug 的快速路由传入的 ID 更新特定的 MongoDB 文档
- scala - 给定方法参数返回最具体的类型