Hi,
I'm trying to use boost::make_transform_iterator to create an iterator for a
custom class whose data is held in a map and where the iterator uses the
vector of keys to access the values.
In my problem, the values of the map are containers which hold large data.
Since I can't afford to copy the data, I would like to access the data by
reference via the iterator. However, when doing this,
the data is corrupted, as is exemplified by the output of the simple
example I have attached. As far as I can tell the problem lies in the use
of the from_key functor, which is initialised using a reference to the map
and is corrupted when passed through make_transform_iterator.
Any ideas how I could do this properly using boost?
Thanks,
Patrick
#include <iostream>
#include <string>
#include <vector>
#include
#include
#include
#include
#include
#include
#include
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& m ) :
map_(m) {};
const holder& operator() ( const std::string& in ) const { return
map_.at(in); };
private:
const boost::unordered_map& map_;
};
typedef boost::transform_iteratorstd::string::iterator > iterator;
int main()
{
std::vectorstd::string keys;
keys += "1","2","3";
std::vector<double> vals;
vals += 1.0, 2.0, 3.0;
holder h(vals);
boost::unordered_map 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;
}