boost::indirect_iterator
Consider this code:
vector<int> coll;
// ... push back some values
vector
Matthias Kaeppler
Consider this code:
vector<int> coll; // ... push back some values vector
ptrcoll; // ... push back pointers to the values of coll indirect_iterator< vector
::iterator > begin(ptrcoll.begin()),
Careful; vector iterators are not neccessarily pointers.
end(ptrcoll.end());
sort( begin, end, less<int> );
--
My question: After the sort statement, coll is sorted, right? (and ptrcoll is not). However, I need to sort a vector of pointers according to a predicate which applies to non-pointers. In this case, I want to sort ptrcoll, according to the less-relation on the pointees in coll.
How can I achieve that?
struct indirect_less
{
template <class It>
bool operator()(It i1, It i2) const
{
typedef typename std::iterator_traits<It>::value_type value_type;
return std::less
David Abrahams wrote:
Careful; vector iterators are not neccessarily pointers.
Hm yes, that's true. But does this matter? I have a vector of some type, and a vector of pointers to some type. I don't even deal with iterators when working on the pointer-vector.
struct indirect_less { template <class It> bool operator()(It i1, It i2) const { typedef typename std::iterator_traits<It>::value_type value_type; return std::less
()(i1,i2); } }; sort(ptrcoll.begin(), ptrcoll.end, indirect_less());
Ah I see. But what, if I want to abstract from the predicate? I want to
create a class which is as generic as possible, so I don't have to
rewrite it for each and every possible predicate.
What if I want to pass the predicate to the constructor of this
template. For one, passing a pointer to a function returning bool and
taking on argument must be possible, and also passing a function object,
maybe of type std::unary_function.
template<typename It>
class indirect
{
const std::unary_function
Matthias Kaeppler wrote:
template<typename It> class indirect { const std::unary_function
& fctor_; public: indirect( const std::unary_function & fctor ): fctor_(fctor) {} bool operator()(It i1, It i2) const { typedef typename std::iterator_traits<It>::value_type value_type; return fctor_ ()(i1,i2); } }; Would that work?
Okay, that doesn't work :) But how would I write such an adaptor? I'm kind of lost. (Actually, I wonder why there isn't already such a thing. It's a pretty common task ain't it). -- Matthias Kaeppler
Matthias Kaeppler
David Abrahams wrote:
Careful; vector iterators are not neccessarily pointers.
Hm yes, that's true. But does this matter? I have a vector of some type, and a vector of pointers to some type. I don't even deal with iterators when working on the pointer-vector.
Sorry, I read your post too quickly and jumped to the wrong conclusion.
struct indirect_less { template <class It> bool operator()(It i1, It i2) const { typedef typename std::iterator_traits<It>::value_type value_type; return std::less
()(i1,i2);
Whoops; I meant:
return std::less
} }; sort(ptrcoll.begin(), ptrcoll.end, indirect_less());
Ah I see. But what, if I want to abstract from the predicate? I want to create a class which is as generic as possible, so I don't have to rewrite it for each and every possible predicate.
I take it from reading this message and your other one that you mean you want to write an adapter for any binary predicate on T that will instead take arguments that can be dereferenced to get Ts and forward those Ts on to the underlying binary predicate (but that's not really clear)? template <class Pred> struct indirector { indirector(Pred const& p) : p(p) {} template <class It> bool operator()(It i1, It i2) const { typedef typename std::iterator_traits<It>::value_type value_type; return p(i1,i2); } Pred p; }; template <class Pred> indirector<Pred> indirect(Pred const& p) { return indirector(p); } sort(ptrcoll.begin(), ptrcoll.end, indirect(less<int>())); HTH -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
David Abrahams
-
Matthias Kaeppler