Thanks for the information.
Jonathan Turkanis wrote:
First, for the example you gave -- which is a common situation -- you
should be able to use indirect_iterators
(http://www.boost.org/libs/iterator/d..._iterator.html)
The indirect_iterator adaptor works fine. However, the resulting
algorithm is a bit different. With indirect_iterator, std::sort works on
objects (in this case integers), while the approach with
pointer_to_reference adaptors works on (smart)pointers.
In the example1.cpp below outputs
vect: 8 0 5 9 1 6 3 4 7 2
copy: 0 1 2 3 4 5 6 7 8 9
vect: 0 1 2 3 4 5 6 7 8 9
copy: 0 1 2 3 4 5 6 7 8 9
vect: 6 1 7 4 2 0 8 5 9 3
copy: 0 1 2 3 4 5 6 7 8 9
vect: 0 1 2 3 4 5 6 7 8 9
copy: 5 1 4 9 3 7 0 2 6 8
Notice that the copy becomes permuted while the original was sorted.
Is there a way to use indirect_iterator in such way that sort replaces
pointers instead of pointed values?
Jonathan Turkanis wrote:
Second, I don't think it's necessary to have two template parameters.
You should be able to calculate the result type given the argument
type (see http://www.boost.org/boost/pointee.hpp.)
This makes the code a bit cleaner. Is there a way to create adaptor
object straight from the pointee<> template? Or is it still necessary to
declare structure that does the trick?
Regards,
Stanislaw
example1.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <stdlib.h>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/bind.hpp>
template <class T>
struct pointer_to_ref
{
typedef T argument_type;
typedef typename boost::pointee<T>::type & result_type;
inline
result_type operator() (argument_type obj)
{
return *obj;
}
};
struct counter
{
typedef int* result_type;
counter () :n (0) {}
result_type operator() () { return new int (n++); }
int n;
};
typedef std::vector<int *> vector_t;
int
main ()
{
srand(time(0));
vector_t v;
std::generate_n (std::back_insert_iterator<vector_t>(v), 10,
counter());
vector_t w (v);
std::random_shuffle (v.begin(), v.end());
std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::sort (v.begin(),
v.end(),
boost::bind(std::less<int>(),
boost::bind(pointer_to_ref<vector_t::value_type>() , _1),
boost::bind(pointer_to_ref<vector_t::value_type>() , _2)));
std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
example2.cpp:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <stdlib.h>
#include <boost/iterator/indirect_iterator.hpp>
struct counter
{
typedef int* result_type;
counter () :n (0) {}
result_type operator() () { return new int (n++); }
int n;
};
typedef std::vector<int *> vector_t;
int
main ()
{
srand(time(0));
vector_t v;
std::generate_n (std::back_insert_iterator<vector_t>(v), 10,
counter());
vector_t w (v);
std::random_shuffle (v.begin(), v.end());
std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::sort (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std::less<int>());
std::cout << "vect: ";
std::copy (boost::make_indirect_iterator(v.begin()),
boost::make_indirect_iterator(v.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::cout << "copy: ";
std::copy (boost::make_indirect_iterator(w.begin()),
boost::make_indirect_iterator(w.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}