Using bind1st for a method that takes argument by reference
std::bind1st and std::bind2nd don't accept functors which take reference arguments, because they themselves form references to these arguments. You can
- use pointers for your function inputs instead of references
- use boost::bind
- accept the performance cost of copying the string
Cannot use std::ptr_fun with function that takes reference
You cannot do this. It is a fundamental limitation to std::bind1st and std::bind2nd. The problem is that it defines two () operators, and one of them already has const & on it. So the compiler sees two identical functions. It won't be fixed since C++11 has already deprecated these methods.
See also:
Using bind1st for a method that takes argument by reference
weird compiler error using bind2nd(): "member function already defined or declared" instead of "reference to reference"
Bind2nd issue with user-defined class
referencing a member function with bind1st and mem_fun
What are you trying to accomplish with bind1st?
The bind1st
function takes a binary function and adapts it to a unary function by making the first argument implicit (this may not be the best description, sorry). The return value of mem_fun
is a unary function.
The mem_fun
function returns an adaptor for a member function. The adapted function doesn't take any arguments, though the adaptor returned takes one argument, a pointer to the MyClass object to be used.
So, basically, your mem_fun
call is returning a adaptor that takes one argument, but bind1st
is expecting an adaptor that takes two arguments. There is a mem_fun1
which returns an adaptor that takes two arguments, the first being the object pointer and the second being an argument for the function, but that isn't what you want here.
In fact, I don't quite understand what you're trying to do; why is the plain mem_fun
version not suitable? If you need the object pointer to be 'attached' to the adaptor, I don't think you can do that with the current standard library, unless you use bind.
Of course, you could make a wrapper class that holds the object pointer, and then just define operator() to call the adaptor with that object.
// Quick and dirty example of this.
// You could extend this with a second template parameter for return type, if
// needed. Just be sure to specialize for void if you do that.
template<typename Object>
struct bound_mem_fun_t {
bound_mem_fun_t(mem_fun_t<void, Object> f, Object* o) : fun(f), obj(o) { }
void operator()() { fun(obj); }
mem_fun_t<void, Object> fun;
Object* obj;
};
MyClass a;
bound_mem_fun_t<MyClass> func(mem_fun(&MyClass::Bar), &a);
func();
How to use bind1st and bind2nd?
The argument to bind2nd
must be an AdaptableBinaryFunction
. A plain binary function does not fulfill this requirement (an adaptable function required typedefs for its return and argument types, a plain function type does not provide any typedefs). You could use std::bind
which is probably the better choice anyway.
Using std::bind2nd with references
You can't do that easily, sorry. Just consider it one of those cases not covered by std::bind1st
and std::bind2nd
(kinda like 3-argument functions etc). Boost would help - boost::bind
supports references transparently, and there's also boost::ref
.
If your implementation supports TR1 - latest g++ versions and VC++2008 SP1 both do - then you can use std::tr1::bind
, which is for the most part same as boost::bind
, but standardized.
std::function and std::bind: what are they, and when should they be used?
std::bind
is for partial function application.
That is, suppose you have a function object f
which takes 3 arguments:
f(a,b,c);
You want a new function object which only takes two arguments, defined as:
g(a,b) := f(a, 4, b);
g
is a "partial application" of the function f
: the middle argument has already been specified, and there are two left to go.
You can use std::bind
to get g
:
auto g = bind(f, _1, 4, _2);
This is more concise than actually writing a functor class to do it.
There are further examples in the article you link to. You generally use it when you need to pass a functor to some algorithm. You have a function or functor that almost does the job you want, but is more configurable (i.e. has more parameters) than the algorithm uses. So you bind arguments to some of the parameters, and leave the rest for the algorithm to fill in:
// raise every value in vec to the power of 7
std::transform(vec.begin(), vec.end(), some_output, std::bind(std::pow, _1, 7));
Here, pow
takes two parameters and can raise to any power, but all we care about is raising to the power of 7.
As an occasional use that isn't partial function application, bind
can also re-order the arguments to a function:
auto memcpy_with_the_parameters_in_the_right_flipping_order = bind(memcpy, _2, _1, _3);
I don't recommend using it just because you don't like the API, but it has potential practical uses for example because:
not2(bind(less<T>, _2, _1));
is a less-than-or-equal function (assuming a total order, blah blah). This example normally isn't necessary since there already is a std::less_equal
(it uses the <=
operator rather than <
, so if they aren't consistent then you might need this, and you might also need to visit the author of the class with a cluestick). It's the sort of transformation that comes up if you're using a functional style of programming, though.
Passing a member function to for_each in C++03 (no boost, no c++11)
Yes it can, using a combination of the mem_fun
and bind1st
templates:
void process(const vector<Wheel>& wheel) {
for_each(wheel.begin(), wheel.end(), bind1st(mem_fun(&Car::put), this));
}
The call to mem_fun
creates a new function object that takes in two arguments - a Car*
to act as the receiver and a Wheel
, then calls put
with the first parameter as the receiver and the second parameter as the argument. Calling bind1st
then locks the receiver object as first parameter of this function in place.
However, I think you will need to make one small change to this code to get it to work. The bind1st
adapter doesn't play well with functions that take their arguments by const reference, so you might need to change put
so that it takes a Wheel
by value rather than by reference.
Using std::vectorT*::push_back with std::mem_fun and std::bind1st
The problem is that binder1st defines operator() as:
operator() (const typename Operation::second_argument_type& x) const
and mem_fun1_t defines operator() as:
S operator() (T* p, A x) const
The problem is that push_back is defined as:
void vector<T>::push_back(const T &x)
So what we end up with is this:
void mem_fun1_t::operator()(vector<T *> *p, const T *&x)
And:
void binder1st::operator()(const T *&&x)
In other words, a reference to a reference to a pointer. A reference to a reference doesn't exist in C++. The only decent way I can think of fixing this is to use boost::bind instead:
vector<T*> ret;
Execute<T>( boost::bind( mem_fun(&vector<T*>::push_back), &ret, _1) );
return ret;
Also note that you had a bug, and need to pass bind &ret instead of just ret (as mem_fun expects a pointer, mem_fun_ref would work however).
Related Topics
Why Do Lambda Functions Drop Deduced Return Type Reference by Default
Is Maximum_Wait_Objects Really 64
C++ Virtual Override Functions with Same Name
Differencebetween String::At and String::Operator[]
Using << Operator to Write to Both a File and Cout
Why "Foo F(Bar());" Can Be a Declaration of a Function That Takes Type Bar and Returns Type Foo
Using an Iterator to Divide an Array into Parts with Unequal Size
Differencebetween Const_Iterator and Iterator
Polymorphism & Pointers to Arrays
Does C++11 Allow Dollar Signs in Identifiers
Pass Arrays from C/C++ to Fortran and Return a Calculated Array
Where Should Non-Member Operator Overloads Be Placed
C++ Regex for Overlapping Matches
Application Has Failed to Start Because Msvcp100D.Dll Was Not Found, Reinstalling App May Work