Re:使用boost :: make_transform_iterator进行引用访问

时间:2011-01-24 22:48:00

标签: c++ boost

我正在尝试使用boost :: make_transform_iterator为自定义类创建迭代器,该数据保存在地图中,迭代器使用键向量来访问值。

在我的问题中,地图的值是容纳大数据的容器。由于我无法复制数据,我想通过迭代器通过引用访问数据。但是,在执行此操作时,数据已损坏,例如我附加的简单示例的输出。

据我所知,问题在于使用from_key仿函数,它是使用对映射的引用初始化的,以及boost :: make_transform_iterator的语义。

任何想法如何使用boost正确地做到这一点?

谢谢,

帕特里克

#include <iostream>
#include <string>
#include <vector>

#include <boost/unordered_map.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/assign.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/ref.hpp>

using namespace boost::assign;
namespace bl = boost::lambda;

class holder
{
    public:
        holder() : v() {};
        holder( const std::vector<double>& in ) : v(in) {};

        std::vector<double>& vector()             { return v; };
        const std::vector<double>& vector() const { return v; };

    private:
        std::vector<double> v;
};

class from_key
{
    public:

        typedef holder result_type;

        from_key( const boost::unordered_map<std::string, holder >& m ) : map_(m) {};

        const holder& operator() ( const std::string& in ) const { return map_.at(in); };

    private:
        const boost::unordered_map<std::string, holder >& map_;
};

typedef boost::transform_iterator<from_key,  std::vector<std::string>::iterator > iterator;

int main()
{
    std::vector<std::string> keys;
    keys += "1","2","3";

    std::vector<double> vals;
    vals += 1.0, 2.0, 3.0;
    holder h(vals);

    boost::unordered_map<std::string, holder > m;
    insert( m ) ( "1", h )
                ( "2", h )
                ( "3", h );

    iterator it  = boost::make_transform_iterator( keys.begin(), from_key( m ) );
    iterator end = boost::make_transform_iterator( keys.begin(), from_key( m ) );

    const std::vector<double>& v = it->vector();

    std::for_each( vals.begin(), vals.end(), std::cout << bl::_1 << " " );
    std::cout << std::endl;
    std::for_each( v.begin(), v.end(), std::cout << bl::_1 << " " );  
    std::cout << std::endl;
}

1 个答案:

答案 0 :(得分:4)

这只是猜测,但是transform_iterator是函数对象和基础迭代器的包装器。如果其解引用运算符的返回类型与您的仿函数的result_type的typedef相同,我不会惊讶。您是否尝试过使用引用类型作为result_type-typedef?

换句话说改变

typedef holder result_type;

typedef holder const& result_type;

看看会发生什么......