remove_if and transform_iterator

Hi, Can transform_iterator be used in conjunction with remove_if algorithm? The compiler (vc7.1, vc8, g++) is refusing to compile this: #include <string> #include <utility> #include <vector> #include <functional> #include <cassert> #include <iostream> #include <boost/iterator/transform_iterator.hpp> std::vector<std::pair<std::string, int> > c; struct to_num { typedef int result_type; int operator()(const std::pair<std::string, int>& p) const { return p.second; } }; int main() { using std::make_pair; c.push_back(make_pair("A", 2)); c.push_back(make_pair("A", 3)); c.push_back(make_pair("A", 4)); c.push_back(make_pair("A", 15)); c.push_back(make_pair("A", 16)); c.push_back(make_pair("A", 17)); assert(c.size() == 6); std::remove_if( boost::make_transform_iterator(c.begin(), to_num()), boost::make_transform_iterator(c.end(), to_num()), std::bind1st(std::less_equal<int>(), 10)); assert(c.size() == 6); } Regards, Josue

Josue Gomes wrote:
Hi,
Can transform_iterator be used in conjunction with remove_if algorithm? The compiler (vc7.1, vc8, g++) is refusing to compile this:
#include <string> #include <utility> #include <vector> #include <functional> #include <cassert> #include <iostream> #include <boost/iterator/transform_iterator.hpp>
std::vector<std::pair<std::string, int> > c;
struct to_num { typedef int result_type;
int operator()(const std::pair<std::string, int>& p) const { return p.second; } };
int main() { using std::make_pair;
c.push_back(make_pair("A", 2)); c.push_back(make_pair("A", 3)); c.push_back(make_pair("A", 4));
c.push_back(make_pair("A", 15)); c.push_back(make_pair("A", 16)); c.push_back(make_pair("A", 17)); assert(c.size() == 6);
std::remove_if( boost::make_transform_iterator(c.begin(), to_num()), boost::make_transform_iterator(c.end(), to_num()), std::bind1st(std::less_equal<int>(), 10));
Are you sure that you want this, even if it did compile? If you apply remove_if+transform_iterator on: A, 2 B, 3 C, 4 D, 15 E, 16 F, 17 you'll get A, 15 B, 16 C, 17 D, -- E, -- F, -- where -- denotes an unspeficied value. If this is the desired result, try struct to_num { typedef int & result_type; int & operator()(std::pair<std::string, int>& p) const { return p.second; } }; If, on the other hand, you want D, 15 E, 16 F, 17 --, -- --, -- --, -- you don't need transform_iterator at all: std::remove_if( c.begin(), c.end(), boost::bind( std::less_equal<int>(), boost::bind( to_num(), _1 ), 10 ) ); (with the original to_num). You can also use &std::pair<std::string, int>::second instead of to_num() and <= 10 instead of less_equal: boost::bind( to_num(), _1 ) <= 10 or boost::bind( &std::pair<std::string, int>::second, _1 ) <= 10

On 12/13/05, Peter Dimov <pdimov@mmltd.net> wrote:
Are you sure that you want this, even if it did compile? If you apply remove_if+transform_iterator on:
A, 2 B, 3 C, 4 D, 15 E, 16 F, 17
you'll get
A, 15 B, 16 C, 17 D, -- E, -- F, --
where -- denotes an unspeficied value.
I was not aware of this. Thanks for pointing out.
If this is the desired result, try
struct to_num { typedef int & result_type;
int & operator()(std::pair<std::string, int>& p) const { return p.second; } };
If, on the other hand, you want
D, 15 E, 16 F, 17 --, -- --, -- --, --
you don't need transform_iterator at all:
std::remove_if( c.begin(), c.end(),
boost::bind( std::less_equal<int>(), boost::bind( to_num(), _1 ), 10 )
);
Thanks. I'm already using this way. I was just wondering if it was possible to use transform_iterator and avoid the functor. Regards, Josue Gomes
participants (2)
-
Josue Gomes
-
Peter Dimov