std::bind2nd and non-const references

R

red floyd

Both gcc 3.3.1 and MSVC 7.1 complain about the second for_each() call
in the following code. Why can't I use bind2nd for a functor with a non-const
reference as the second parameter? I have to use kludge it by using something like
KludgeFunctor().

---------------------------
#include <vector>
#include <algorithm>
#include <functional>

class A {
public:
A() { }
A(const A&) { }
};

class B {
public:
B() { }
B(const B&) { }
};

class GoodFunctor : public std::binary_function<A, B, void>
{
public:
void operator()(const A&, const B&) const { }
};

class BadFunctor : public std::binary_function<A, B, void>
{
public:
void operator()(const A&, B&) const { }
};


class KludgeFunctor : public std::unary_function<A, void>
{
B& b;
public:
KludgeFunctor(B& b_) : b(b_) { }
void operator()(const A&) const { }
};

void f()
{
std::vector<A> v;
B b;

// this compiles
std::for_each(v.begin(),
v.end(),
std::bind2nd(GoodFunctor(), b));

// this generates an error
std::for_each(v.begin(),
v.end(),
std::bind2nd(BadFunctor(), b));

// this is the workaround for BadFunctor
std::for_each(v.begin(),
v.end(),
KludgeFunctor(b));
}
----------------------------------
 
J

Jeff Schwab

red said:
Both gcc 3.3.1 and MSVC 7.1 complain about the second for_each() call
in the following code. Why can't I use bind2nd for a functor with a
non-const
reference as the second parameter? I have to use kludge it by using
something like
KludgeFunctor().

---------------------------
#include <vector>
#include <algorithm>
#include <functional>

class A {
public:
A() { }
A(const A&) { }
};

class B {
public:
B() { }
B(const B&) { }
};

class GoodFunctor : public std::binary_function<A, B, void>
{
public:
void operator()(const A&, const B&) const { }
};

class BadFunctor : public std::binary_function<A, B, void>
{
public:
void operator()(const A&, B&) const { }
};


class KludgeFunctor : public std::unary_function<A, void>
{
B& b;
public:
KludgeFunctor(B& b_) : b(b_) { }
void operator()(const A&) const { }
};

void f()
{
std::vector<A> v;
B b;

// this compiles
std::for_each(v.begin(),
v.end(),
std::bind2nd(GoodFunctor(), b));

// this generates an error
std::for_each(v.begin(),
v.end(),
std::bind2nd(BadFunctor(), b));

// this is the workaround for BadFunctor
std::for_each(v.begin(),
v.end(),
KludgeFunctor(b));
}
----------------------------------

std::bind2nd takes a const reference as its second argument; see the
following code from the gcc stl_function.h header. It shouldn't be
difficult to roll your own version of bind2nd to use a non-const reference.

template <class _Operation, class _Tp>
inline binder2nd<_Operation>
bind2nd(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(__fn, _Arg2_type(__x));
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top