Topic: using std::bind2nd and std::mem_fun_ref
Author: Joel Reed <jreed@ddiworld.COM>
Date: 2000/01/01 Raw View
I'm using gcc-2.95.2 and am having problems with std::bind2nd.
it seems that gcc doesn't like:
std::for_each(q.begin(), q.end(), std::bind2nd(std::mem_fun_ref(&person::mature), 2));
i think its because std::bind2nd takes a const Predicate. (really not sure though)
but gcc says...
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.1/../../../../include/g++-3/stl_function.h: In method `void binder2nd<mem_fun1_ref_t<void,person,int> >::operator ()(const person &) const':
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.1/../../../../include/g++-3/stl_algo.h:83: instantiated from `for_each<reverse_iterator<_Deque_iterator<person,person &,person *,0> >, binder2nd<mem_fun1_ref_t<void,person,int> > >(reverse_iterator<_Deque_iterator<person,person &,person *,0> >, reverse_iterator<_Deque_iterator<person,person &,person *,0> >, binder2nd<mem_fun1_ref_t<void,person,int> >)'
tmp.cpp:30: instantiated from here
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.1/../../../../include/g++-3/stl_function.h:224: conversion from `const person' to `person &' discards qualifiers
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.1/../../../../include/g++-3/stl_function.h:622: in passing argument 1 of `mem_fun1_ref_t<void,person,int>::operator ()(person &, int) const'
Is there a better way (one that compiles!) to do the above? I did discover that
if I make person::mature(int) a const & person::age a mutable that it compiles
and runs, but that seems pretty ugly.
i also tried q.rbegin() & q.rend() to make sure i was getting a iterator and
not a const_iterator (from q.begin()) but that didn't help.
here's the whole test program:
#include <iostream>
#include <algorithm>
#include <deque>
#include <functional>
struct person
{
person(int a) : age(a) {}
void mature(int i=0) { age+=i; }
int age;
};
std::ostream& operator << (std::ostream& os, const person& p)
{
os << "person " << (int)&p << " is " << p.age << " years old.\n";
return os;
}
typedef std::deque<person> iq_t;
template <class T> T& element (T& t) { return t; };
void main()
{
iq_t q;
person p1(1), p2(2), p4(4), p8(8);
q.push_back(p1); q.push_back(p2); q.push_back(p4); q.push_back(p8);
std::copy(q.begin(), q.end(), std::ostream_iterator<person>(std::cout));
std::for_each(q.begin(), q.end(), std::bind2nd(std::mem_fun_ref(&person::mature), 2));
std::copy(q.begin(), q.end(), std::ostream_iterator<person>(std::cout));
}
thanks for any help,
jr
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Darin Adler <darin@bentspoon.com>
Date: 2000/01/02 Raw View
Joel Reed <jreed@ddiworld.COM> wrote:
> I'm using gcc-2.95.2 and am having problems with std::bind2nd.
>
> it seems that gcc doesn't like:
>
> std::for_each(q.begin(), q.end(),
> std::bind2nd(std::mem_fun_ref(&person::mature), 2));
>
> i think its because std::bind2nd takes a const Predicate. (really not sure
> though)
This is a flaw in the C++ Standard, not in gcc. There are no versions of
bind2nd and the related templates where the unbound parameters are
non-const. Thus, when you use mem_fun_ref with a non-const member function,
you get a function object that can't be used with bind2nd.
Bjarne Stroustrup noticed this problem and reported it to the C++ Standards
Committee. It is currently under consideration by the library working group
as issue #109, "Missing binders for non-const sequence elements"
<http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#109>.
Note that this comes up in Josuttis's C++ Library book as well. See the
section 8.2.2 part of <http://www.josuttis.com/libbook/errata1_3.html>.
-- Darin
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]