标签: iterator

spled()on std :: list和iterator invalidation

3参数形式list::splice()将单个元素从一个列表移动到另一个列表. SGI的文档明确声明所有迭代器,包括指向要移动的元素的迭代器仍然有效. Roguewave的文档没有说明splice()方法的迭代器失效属性,而C++标准明确声明它使所有迭代器和对被拼接元素的引用无效.

splicing()在实践中按照SGI的定义工作,但是我在微软的STL实现的调试/安全SCL版本中得到断言失败(解除引用无效迭代器)(严格遵循标准的字母).

现在,我正在使用list完全是因为我想在列表之间移动一个元素,同时保留指向它的迭代器的有效性.该标准对最初的SGI规范进行了极为无益的改变.

我该如何解决这个问题?或者我应该是务实,在沙把头(因为拼接并没有在实践中迭代器失效-甚至在MS的执行,一旦调试迭代器关闭).

c++ containers iterator list

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

为什么我们需要在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
查看次数

std :: iterator,指针和VC++警告C4996

int *arr = (int*) malloc(100*sizeof(int));
int *arr_copy = (int*) malloc(100*sizeof(int));
srand(123456789L);
for( int i = 0; i < 100; i++) {
    arr[i] = rand();
    arr_copy[i] = arr[i];
}

// ------ do stuff with arr ------

// reset arr...
std::copy(arr_copy, arr_copy+100,  arr);
Run Code Online (Sandbox Code Playgroud)

在编译时,我得到以下警告std::copy():

c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2227):
warning C4996: 'std::_Copy_impl': Function call with parameters that may be
unsafe - this call relies on the caller to check that the passed values are 
correct. To disable this warning, …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm iterator stl

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

为什么gcc使用我的自定义迭代器优化了这个C++ 11 foreach循环?

我试图编写一些代码来进行序列的功能式创建.我编写了一个函数,range(a, b)它返回一个可以迭代的对象,foreach-style,遍历数字a,a + 1,...,b - 1.然后我写了另一个函数map(f, t),它返回另一个函数对象,其中序列中的每个元素都是f使用可迭代对象的相应元素进行调用的结果t.

如果我使用-O1或更低编译,这可以按预期工作; 有了-O2或更高,我的foreach循环(在main底部)得到完全优化,没有任何打印.为什么会这样,我做错了什么?这是我的代码:

template<typename T>
struct _range {
    T a;
    T b;

    _range(T a, T b):
        a(a),
        b(b)
    {
    }

    struct iterator {
        T it;

        iterator(T it):
            it(it)
        {
        }

        bool operator!=(const iterator &other) const
        {
            return it != other.it;
        }

        void operator++()
        {
            ++it;
        }

        T operator*() const
        {
            return it;
        }
    };

    iterator begin() const
    {
        return iterator(a); …
Run Code Online (Sandbox Code Playgroud)

c++ foreach iterator c++11

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

我如何迭代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
查看次数

为什么迭代器在Python文档中被认为是函数式的?

我试图理解迭代器.我注意到Python文档认为迭代器是一个功能样式的构造.我真的不明白.

迭代器里面有一个状态是不是真的.所以当你调用时it.__next__(),你会改变迭代器的状态.据我所知,对象的变异状态不被认为是功能性的,因为函数式编程强调对象/闭包的不变性和组合能力.

实际上,问题出现了,因为我想编写一个Scheme过程/函数,它接受令牌并返回一个迭代器.

(define tokens->iterator
  (lambda ls
    (lambda ()
      (if (null? ls)
          '*eoi*
          (let ((tok (car ls)))
            (set! ls (cdr ls))
            tok)))))
Run Code Online (Sandbox Code Playgroud)

请注意我必须使用set!变异ls,这就是我提出这个问题的方法.

要使用它,

(define it (tokens->iterator 1 '+ 2))
Run Code Online (Sandbox Code Playgroud)

要测试它,

scheme@(guile-user)> (it)
$2 = 1
scheme@(guile-user)> (it)
$3 = +
scheme@(guile-user)> (it)
$4 = 2
scheme@(guile-user)> (it)
$5 = *eoi*
scheme@(guile-user)> (it)
$6 = *eoi*
Run Code Online (Sandbox Code Playgroud)

只是为了好玩,我还将其翻译成Python:

def tokens_to_iterator(*tup):
    ls = list(tup)
    def iterator():
        if not ls:
            return "*eoi*"
        else:
            tok = …
Run Code Online (Sandbox Code Playgroud)

python scheme iterator

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

为什么范围的算法与std的迭代器不兼容?

#include <vector>
#include <iostream>
#include <range/v3/all.hpp>

int main()
{
    auto coll = std::vector{ 1, 2, 3 };

    ranges::copy(
        coll,
        ranges::ostream_iterator<int>{  std::cout, ", " }
    ); // ok

    ranges::copy(
        coll, 
        std::ostream_iterator<int>{ std::cout, ", " }
    ); // error 
}
Run Code Online (Sandbox Code Playgroud)

问题显示在上面的代码中.我使用range-v3-0.3.7.

对我来说,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求即可.

如果是这样,为什么范围的算法不与std的迭代器兼容?

c++ iterator c++-concepts range-v3 c++20

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