是back_insert_iterator<>安全的价值?

时间:2010-03-29 10:15:13

标签: c++ stl iterator

我的代码类似于:

struct Data { int value; };
class A {
public:
    typedef std::deque<boost::shared_ptr<Data> > TList;
    std::back_insert_iterator<TList> GetInserter()
    {
        return std::back_inserter(m_List);
    }
private:
    TList m_List;
};
class AA {
    boost::scoped_ptr<A> m_a;
public:
    AA() : m_a(new A()) {}
    std::back_insert_iterator<A::TList> GetDataInserter()
    {
        return m_a->GetInserter();
    }        
};
class B {
    template<class OutIt>
    CopyInterestingDataTo(OutIt outIt)
    {
        // loop and check conditions for interesting data
        // for every `it` in a Container<Data*>
        // create a copy and store it
        for( ... it = ..; .. ; ..) if (...) {
            *outIt = OutIt::container_type::value_type(new Data(**it));
            outIt++; // dummy
        }
    }
    void func()
    {
        AA aa;
        CopyInterestingDataTo(aa.GetDataInserter());
        // aa.m_a->m_List is empty!
    }
};

问题是A::m_List即使在调用CopyInterestingDataTo()后也始终为空。但是,如果我调试并进入CopyInterestingDataTo(),迭代器会存储所谓的插入数据!

更新 我找到了罪魁祸首。我实际上有类似的东西:

class AA {
    boost::scoped_ptr<A> m_a;
    std::back_insert_iterator<A::TList> GetDataInserter()
    {
        //return m_a->GetInserter(); // wrong
        return m_A->GetInserter(); // this is the one I actually want
    }        
    // ..... somewhere at the end of the file
    boost::scoped_ptr<A> m_A;
};

现在,我应该将答案标记为答案? 对于那些没有被选中的人真的很抱歉,但你们肯定得到了一些赞成票:)

2 个答案:

答案 0 :(得分:4)

简短的回答是肯定的,back_insert_iterator通过值传递是安全的。答案很长:从标准24.4.2 / 3:

  

插入迭代器满足   输出迭代器的要求。

和24.1.2 / 1

  

类或内置类型X满足   输出迭代器的要求   如果X是可分配类型(23.1)...

最后来自23.1中的表64:

  

表达 t = u   返回类型 T&   后置条件 t相当于u

编辑:您的代码一目了然,您是否100%确定元素实际上已被插入?如果你是我,我会单步执行代码并检查aa.m_a->m_List对象的地址,并将其与outItCopyInterestingDataTo中存储的对象进行比较,如果它们不是同一个东西的话腥。

答案 1 :(得分:1)

以下编译的代码打印“1”,表示添加到列表中的一个项目:

#include <iostream>
#include <deque>
#include "boost/shared_ptr.hpp"
#include "boost/scoped_ptr.hpp"

struct Data { 
    int value; 
    Data( int n ) : value(n) {}
};

struct A {
    typedef std::deque<boost::shared_ptr<Data> > TList;
    std::back_insert_iterator<TList> GetInserter()
    {
        return std::back_inserter(m_List);
    }
    TList m_List;
};

struct AA {
    boost::scoped_ptr<A> m_a;
    AA() : m_a(new A()) {}
    std::back_insert_iterator<A::TList> GetDataInserter()
    {
        return m_a->GetInserter();
    }        
};

struct B {
    template<class OutIt>
    void CopyInterestingDataTo(OutIt outIt)
    {
        *outIt = typename OutIt::container_type::value_type(new Data(0));
        outIt++; // dummy
    }
    int func()
    {
        AA aa;
        CopyInterestingDataTo(aa.GetDataInserter());
        return aa.m_a->m_List.size();
    }
};

int main() {
    B b;
    int n = b.func();    
    std::cout <<  n << std::endl;
}