标签: iterator

为什么我们需要在c#中使用迭代器?

有人可以提供关于迭代器使用的真实例子.我试着搜索谷歌,但对答案不满意.

c# iterator

11
推荐指数
3
解决办法
4875
查看次数

使用boost :: iterator

我写了一个稀疏的矢量类(参见#1,#2.)

我想提供两种迭代器:

第一个集合,即常规迭代器,可以指向任何元素,无论是设置还是未设置.如果它们被读取,它们将返回设置值,或者value_type(),如果它们被写入,则它们创建元素并返回左值引用.因此,它们是:

随机访问遍历迭代器可读可写迭代器

第二个集合,即稀疏迭代器,仅迭代set元素.由于他们不需要懒惰地创建写入的元素,因此它们是:

随机访问遍历迭代器可读可写左值迭代器

我还需要两者的const版本,这些版本都是不可写的.

我可以填写空白,但不知道如何使用boost :: iterator_adaptor开始.

这是我到目前为止所拥有的:

template<typename T>
class sparse_vector {
public:
    typedef size_t size_type;
    typedef T value_type;

private:
    typedef T& true_reference;
    typedef const T* const_pointer;
    typedef sparse_vector<T> self_type;
    struct ElementType {
        ElementType(size_type i, T const& t): index(i), value(t) {}
        ElementType(size_type i, T&& t): index(i), value(t) {}
        ElementType(size_type i): index(i) {}
        ElementType(ElementType const&) = default;
        size_type index; …
Run Code Online (Sandbox Code Playgroud)

c++ boost iterator boost-iterators

11
推荐指数
1
解决办法
8119
查看次数

如何确保迭代器不会超越end()?

我一直在使用advance一些iterators,但恐怕上述可能的越级end().我想确保我的迭代器保持在界限之间,我想到了distance但似乎它没有返回我期望的东西(迭代器超越时的非正值end()).你怎么能确保没有越级?

#include <iostream>
#include <iterator>
#include <list>
using namespace std;

int main () {
  list<int> mylist;
  for (int i=0; i<10; i++) mylist.push_back (i*10);

  list<int>::const_iterator first = mylist.begin();
  const list<int>::const_iterator last = mylist.end();

  cout << "The distance is: " << distance(first,last) << endl; // 10
  advance(first, 10);
  cout << "The distance is: " << distance(first,last) << endl; // 0
  advance(first, 1);
  cout << "The distance is: " << distance(first,last) << endl; …
Run Code Online (Sandbox Code Playgroud)

c++ iterator distance stdlist

11
推荐指数
3
解决办法
9186
查看次数

在erase()之后保持有效的vector :: iterator

编辑:我有很多答案告诉我,我应该将删除分成另一个循环.也许我没有说清楚,但我在上一段中说过,我想找到一个解决方法.即保持当前的代码结构,但使用一些鲜为人知的C++ fu来使其工作.

好吧,我知道调用erase()一个向量会使元素的迭代器和它之后的所有迭代器失效,并且erase()会将迭代器返回到下一个有效的迭代器,但是如果擦除发生在其他地方呢?

我有以下情况(简化):

警告:不要认为这是整个代码.下面显示的内容非常简单,以说明我的问题.下面显示的所有类和方法实际上要复杂得多.

class Child {
   Parent *parent;
}

class Parent {
   vector<Child*> child;
}

void Parent::erase(Child* a) {
   // find an iterator, it, that points to Child* a
   child.erase(it);
}

int Child::update() {
   if(x()) parent.erase(*this) // Sometimes it will; sometimes (most) it won't
   return y;
}

void Parent::update() {
   int i = 0;
   for(vector<A>::iterator it = child.begin(); it != child.end(); it++)
      i += (*it)->update();
}
Run Code Online (Sandbox Code Playgroud)

因此,很明显,(*it)->update()如果x()返回true ,它会在运行后崩溃,因为当它执行时,Child会告诉Parent将它从向量中移除,使迭代器无效.

有没有什么方法可以解决这个问题,而不是让Parent::erase() …

c++ iterator

11
推荐指数
2
解决办法
6617
查看次数

函数在C++中返回迭代器

以下是返回迭代器的Java方法

vector<string> types;

// some code here

Iterator Union::types() 
{
    return types.iterator();
}
Run Code Online (Sandbox Code Playgroud)

我想将此代码翻译为C++.如何从此方法返回vector的迭代器?

c++ iterator

11
推荐指数
2
解决办法
4万
查看次数

是 - >为迭代器my_map.end()定义的第二个?

我正在和一个人一起工作std::map<std::string, MyClass* >.

我想测试是否my_map.find(key)返回特定指针.

现在我正在做;

auto iter = my_map.find(key);
if ((iter != my_map.end()) && (iter->second == expected)) {
    // Something wonderful has happened
}
Run Code Online (Sandbox Code Playgroud)

但是,operator *迭代器的位置需要返回引用.直觉我认为它是有效的并完全初始化?如果是这样,那my_map.end()->second将是NULL,并且(因为NULL从未预料到),我可以将我的if语句减少为:

if (iter->second == expected)
Run Code Online (Sandbox Code Playgroud)

这是否符合规范?有没有人有实际经验?恕我直言,代码变得更加清晰,可能会实现微小的性能提升.

c++ iterator stl

11
推荐指数
1
解决办法
3297
查看次数

我如何迭代Haxe中的枚举?

我有一个枚举器类型:

enum PlayerProps {
    Attempts;
    Gold;
    Diamonds;
}
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能遍历所有枚举值?就像是:

var props = new Map<PlayerProps, Int>();
for (prop in PlayerProps)
    props[prop] = 0;
Run Code Online (Sandbox Code Playgroud)

enums iterator haxe

11
推荐指数
1
解决办法
1272
查看次数

标准库中的boost :: make_transform_iterator相当于什么?

处理const向量时,以下方法不起作用:

const std::vector<std::string> v;
v.push_back("test"); // error: v cannot be modified
Run Code Online (Sandbox Code Playgroud)

相反,您必须在构造它的同一行初始化向量.但是,即使有这个限制,boost::make_transform_iterator也可以在将它们推入v之前轻松地使用另一个vector的元素.在这个例子中,convert是一个返回输入元素的转换版本的一元函数:

auto beg = boost::make_transform_iterator(args.begin(), convert);
auto end = boost::make_transform_iterator(args.end(), convert);

const std::vector<const char*> vc { beg, end };
Run Code Online (Sandbox Code Playgroud)

我已经看了可用的功能<iterator>,但没有看到等效功能.它只是缺失或标准库没有它的原因吗?

c++ boost iterator c++11

11
推荐指数
1
解决办法
3507
查看次数

Scala for循环和迭代器

让我们假设我有一个非常大的可迭代值集合(大约100,000个字符串条目,逐个从磁盘读取),我在其笛卡尔积上做了一些事情(并将结果写回磁盘,但我不会在这里显示):

for(v1 <- values; v2 <- values) yield ((v1, v2), 1)
Run Code Online (Sandbox Code Playgroud)

我知道这只是另一种写作方式

values.flatMap(v1 => values.map(v2 => ((v1, v2), 1)))
Run Code Online (Sandbox Code Playgroud)

这显然导致每个flatMap迭代(甚至整个笛卡尔积?)的整个集合保存在内存中.如果你使用for循环读取第一个版本,这显然是不必要的.理想情况下,只应将两个条目(正在组合的条目)保存在内存中.

如果我重新制定第一个版本:

for(v1 <- values.iterator; v2 <- values.iterator) yield ((v1, v2), 1)
Run Code Online (Sandbox Code Playgroud)

内存消耗要低很多,这让我认为这个版本必须根本不同.它在第二个版本中的确有何不同?为什么Scala不会隐式使用第一个版本的迭代器?在某些情况下不使用迭代器时是否有任何加速?

谢谢!(还要感谢"lmm"谁回答了这个问题的早期版本)

iterator loops scala

11
推荐指数
2
解决办法
7609
查看次数

如何使用解构赋值来定义ES6中的枚举?

您可以使用解构分配来定义ES6中的枚举,如下所示:

var [red, green, blue] = [0, 1, 2];
Run Code Online (Sandbox Code Playgroud)

相反,我希望解构分配的右侧是动态的.例如:

var MAX_ENUM_SIZE = 32;
var ENUM = new Array(MAX_ENUM_SIZE);
for (var i = 0; i < MAX_ENUM_SIZE; i++) ENUM[i] = i;

var [red, green, blue] = ENUM;
Run Code Online (Sandbox Code Playgroud)

不幸的是,这似乎是一个黑客.如果我希望将来有更大的枚举怎么办?因此,我正在考虑使用迭代器进行解构赋值,如下所示:

var [red, green, blue] = enumeration(/* I don't want to specify size */);
Run Code Online (Sandbox Code Playgroud)

但是,我不认为可以使用迭代器进行解构赋值[需要引证].有没有办法实现这个目标?

javascript enums iterator destructuring ecmascript-6

11
推荐指数
1
解决办法
261
查看次数