标签: iterator

为什么我得到错误'vector iterators incompatible'?

我正在为我的程序编写一个小UI.我有方法onMouseMotion(),我可以用两种方式之一调用(参见代码); 如果我通过它std::function,那么!=for循环停止条件中的运算符会产生运行时异常vector iterators incompatible.为什么?

class Widget : public EventHandler
{
protected:
    /* ... */
    std::vector<Widget *> children_;                        
    std::function<bool(Event &)> func_;

private:
    bool onMouseMotion(Event &event);
    /* ... */   
};

Widget::Widget() 
{
    /* ... */
    func_ = std::bind(&Widget::onMouseMotion, this, std::placeholders::_1);
    /* ... */
}

bool Widget::processEvent(Event &event)
{
    if (event.getType() == ui::EventType::MouseMotionEvent) {

        /* Method 1 - onMouseMotion works ok */     
        onMouseMotion(event);

        /* Method 2 - onMouseMotion throws */
        //func_(event);

        return true;
    }
} …
Run Code Online (Sandbox Code Playgroud)

c++ iterator vector visual-c++ std-function

7
推荐指数
1
解决办法
459
查看次数

使用迭代器遍历boost :: ublas矩阵

我只是想从头到尾遍历矩阵,触及每个元素.但是,我看到没有一个迭代器用于boost矩阵,而是有两个迭代器,我无法弄清楚如何使它们工作以便你可以遍历整个矩阵

    typedef boost::numeric::ublas::matrix<float> matrix;

    matrix m1(3, 7);

    for (auto i = 0; i < m1.size1(); i++)
    {
        for (auto j = 0; j < m1.size2(); j++)
        {
            m1(i, j) = i + 1 + 0.1*j;
        }
    }

    for (auto itr1 = m1.begin1(); itr1!= m1.end1(); ++itr1)
    { 
        for (auto itr2 = m1.begin2(); itr2 != m1.end2(); itr2++)
        {
            //std::cout << *itr2  << " ";
            //std::cout << *itr1  << " ";
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的这个代码,使用itr1只打印矩阵的第1行,使用itr2只打印矩阵的第1列.可以做些什么来代替访问所有行和列?

c++ boost iterator matrix ublas

7
推荐指数
1
解决办法
2442
查看次数

在Python中实现深度优先树迭代器

我正在尝试在Python中为不一定二进制树实现迭代器类.在使用树的根节点构造迭代器之后,next()可以重复调用其函数以按深度优先顺序(例如,此顺序)遍历树,最后None在没有剩余节点时返回.

这是Node树的基本类:

class Node(object):

    def __init__(self, title, children=None):
        self.title = title
        self.children = children or []
        self.visited = False   

    def __str__(self):
        return self.title
Run Code Online (Sandbox Code Playgroud)

正如您在上面所看到的,我visited为第一种方法向节点引入了一个属性,因为我没有看到它的方法.通过额外的状态测量,Iterator该类看起来像这样:

class Iterator(object):

    def __init__(self, root):
        self.stack = []
        self.current = root

    def next(self):
        if self.current is None:
            return None

        self.stack.append(self.current)
        self.current.visited = True

        # Root case
        if len(self.stack) == 1:
            return self.current

        while self.stack:
            self.current = self.stack[-1] 
            for child in self.current.children:
                if not child.visited: …
Run Code Online (Sandbox Code Playgroud)

python algorithm tree iterator depth-first-search

7
推荐指数
1
解决办法
7051
查看次数

std :: begin和R-values

最近我试图修复一个相当困难的const-correctness编译器错误.它最初表现为Boost.Python内部的多段模板呕吐错误.

但这是无关紧要的:这一切都归结为以下事实:C++ 11 std::beginstd::end迭代器函数不会重载以获取R值.

定义std::begin是:

template< class C >
auto begin( C& c ) -> decltype(c.begin());

template< class C >
auto begin( const C& c ) -> decltype(c.begin());
Run Code Online (Sandbox Code Playgroud)

因此,由于没有R值/通用引用重载,如果您传递一个R值,您将获得一个const迭代器.

那我为什么要关心?好吧,如果您有某种"范围"容器类型,即像"视图","代理"或"切片"或某些容器类型,它们呈现另一个容器的子迭代器范围,通常非常方便使用R值语义并从临时切片/范围对象中获取非const迭代器.但是std::begin,你运气不好因为std::begin总会返回一个R值的常量迭代器.这是一个老问题,C++ 03程序员经常在C++ 11给我们R值的前一天感到沮丧 - 即临时问题始终具有约束力const.

那么,为什么没有std::begin定义为:

template <class C>
auto begin(C&& c) -> decltype(c.begin());
Run Code Online (Sandbox Code Playgroud)

这样,如果c是常数,我们得到a C::const_iterator和a C::iterator否则.

起初,我认为原因是为了安全.如果你传递了一个临时的std::begin,就像这样:

auto it = std::begin(std::string("temporary string")); // never do this
Run Code Online (Sandbox Code Playgroud)

...你得到一个无效的迭代器.但后来我意识到这个问题仍然存在于当前的实现中.上面的代码只会返回一个无效的const -iterator,在解除引用时可能会出现段错误.

那么,为什么std::begin …

c++ iterator c++11

7
推荐指数
1
解决办法
495
查看次数

如何为按需构造其值的迭代器实现operator->?

我有一个C++类,它像一个容器:它有size()operator[]成员函数.存储在容器中的值是std::tuple对象.但是,容器实际上并没有将元组保存在内存中; 相反,它根据以不同形式存储的基础数据按需构建它们.

std::tuple<int, int, int>
MyContainer::operator[](std::size_t n) const {
    // Example: draw corresponding elements from parallel arrays
    return { underlying_data_a[n], underlying_data_b[n], underlying_data_c[n] };
}
Run Code Online (Sandbox Code Playgroud)

因此,返回类型operator[]是临时对象,而不是引用.(这意味着它不是左值,因此容器是只读的;没关系.)

现在我正在编写一个迭代器类,可用于遍历此容器中的元组.我想建模RandomAccessIterator,它依赖于InputIterator,但是InputIterator需要支持表达式i->m(其中i是一个迭代器实例),据我所知,operator->需要一个函数来返回一个指针.

当然,我无法返回指向按需构建的临时元组的指针.想到的一种可能性是将一个元组实例作为成员变量放入迭代器中,并使用它来存储迭代器当前所处的任何值的副本:

class Iterator {
private:
    MyContainer *container;
    std::size_t current_index;

    // Copy of (*container)[current_index]
    std::tuple<int, int, int> current_value;
    // ...
};
Run Code Online (Sandbox Code Playgroud)

但是,更新存储的值将要求迭代器检查其当前索引是否小于容器的大小,以便过去的迭代器不会通过访问基础数组的末尾来导致未定义的行为.这增加了(少量)运行时开销 - 当然不足以使解决方案变得不切实际,但感觉有点不雅.迭代器不应该真正存储任何东西,只能指向它正在迭代的容器的指针以及它内部的当前位置.

是否有一种干净,完善的方式来支持operator->按需构建其值的迭代器类型?其他开发人员将如何做这类事情?

(请注意,我根本不需要支持operator->- 我主要是实现迭代器,以便可以使用C++ 11" for循环遍历容器,并且std::tuple …

c++ iterator operator-overloading c++11

7
推荐指数
1
解决办法
645
查看次数

Java HashMap在迭代时添加新条目

在HashMap中

map = new HashMap<String,String>();

it = map.entrySet().iterator();
while (it.hasNext())
{
    entry = it.next();
    it.remove(); //safely remove a entry
    entry.setValue("new value"); //safely update current value
    //how to put new entry set inside this map
    //map.put(s1,s2); it throws a concurrent access exception

}
Run Code Online (Sandbox Code Playgroud)

当我试图添加一个新的条目来映射它抛出ConcurrentModificationException.对于删除和更新,迭代器已安全地删除方法.如何在迭代时添加新条目?

java iterator concurrentmodification

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

迭代字符串中子字符串的位置

我正在寻找如何迭代字符串中子字符串位置的最简单方法.目前我正在使用一个生成器,但我觉得它不是Python:

def iteratePos(haystack, needle) :
    pos = haystack.find(needle)
    while pos >= 0 :
        yield pos
        pos = haystack.find(needle, pos+1)

s = "ABC 11 ABC 111 ABC 1"
for i in iteratePos(s, "ABC") :
    print "aye bee see at", i
    # finds 0, 7, 15

for i in iteratePos(s, "1") :
    print "one at", i
    # finds 4, 5, 11, 12, 13, 19
Run Code Online (Sandbox Code Playgroud)

那么,是否有可能将其作为一个合理的单行程?或者我应该坚持我的解决方案?

(注意:当needle只有一个字符时,是否应该有一个简单的解决方案,我也对此感兴趣.)

python string search iterator

7
推荐指数
1
解决办法
2788
查看次数

返回依赖于函数内分配的数据的延迟迭代器

我是Rust的新手并阅读了Rust编程语言,在错误处理部分有一个"案例研究",描述了一个程序,使用csvrustc-serialize库(getopts用于参数解析)从CSV文件中读取数据.

作者编写了一个函数search,该函数使用一个csv::Reader对象逐步执行csv文件的行,并将那些"city"字段与指定值匹配的条目收集到一个向量中并返回它.我采取了与作者略有不同的方法,但这不应该影响我的问题.我的(工作)函数看起来像这样:

extern crate csv;
extern crate rustc_serialize;

use std::path::Path;
use std::fs::File;

fn search<P>(data_path: P, city: &str) -> Vec<DataRow>
    where P: AsRef<Path>
{
    let file = File::open(data_path).expect("Opening file failed!");
    let mut reader = csv::Reader::from_reader(file).has_headers(true);

    reader.decode()
          .map(|row| row.expect("Failed decoding row"))
          .filter(|row: &DataRow| row.city == city)
          .collect()
}
Run Code Online (Sandbox Code Playgroud)

DataRow类型仅仅是一个记录,

#[derive(Debug, RustcDecodable)]
struct DataRow {
    country: String,
    city: String,
    accent_city: String,
    region: String,
    population: Option<u64>, …
Run Code Online (Sandbox Code Playgroud)

iterator allocation heap-memory lifetime rust

7
推荐指数
1
解决办法
342
查看次数

C++迭代器是否包含对底层对象的引用?

我似乎无法找到关于迭代器是否保持它们迭代的底层对象的大量信息.

如果我创建一个迭代器,那么提供它的对象超出了范围,迭代器的存在是否会阻止它被破坏?

这是一个非常简单的例子,仅用于说明该场景:

// This class takes a copy of iterators to use them later
class Data {
  public:
    Data(std::vector<int>::iterator start, std::vector<int>::iterator end)
      : start(start),
        end(end)
    {}

    void show() {
      // Use this->start and this->end for some purpose
    }

  private:
    std::vector<int>::iterator start;
    std::vector<int>::iterator end;
};

Data test() {
  std::vector<int> v{1, 2, 3};
  Data d(v.begin(), v.end());
  d.show(); // this would be ok
  return d;
}

int main(void) {
  Data d = test();
  d.show();  // What happens here?
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,Data对象正在存储迭代器的副本,这对第一次 …

c++ iterator reference

7
推荐指数
1
解决办法
2166
查看次数

检测对象是否可重复迭代

是否obj == iter(obj)意味着obj不能重复迭代,反之亦然?我没有在文档中看到任何这样的措辞,但根据这个评论,标准库通过测试检查对象是否可重复迭代 :if iter(obj) is obj

@agf:Python标准库的某些部分依赖于规范的这一部分; 它们通过测试检测某些东西是否是迭代器/生成器if iter(obj) is obj:,因为真正的迭代器/生成器对象将__iter__定义为标识函数.如果测试为真,则转换为list允许重复迭代,否则,假设对象可重复迭代,并且可以按原样使用它.
- ShadowRanger 6月3日17:23

文档确实声明如果obj是迭代器,则需要iter(obj)返回obj.但我认为这并不足以得出结论,可以使用非重复可迭代对象来识别iter(obj) is obj.

python iterator python-3.x

7
推荐指数
1
解决办法
109
查看次数