Does Boost::Bind() Copy Parameters by Reference or by Value

Does boost::bind() copy parameters by reference or by value?

By value. 1

But you can make it copy by ref instead:

void SomeFunction(const int& value)
{
boost::bind(..., boost::ref(value));
boost::bind(..., boost::cref(value)); // by const ref
}

1 http://www.boost.org/doc/libs/1_46_1/libs/bind/bind.html#Purpose

a copy of the value of i is stored into the function object. boost::ref and boost::cref can be used to make the function object store a reference to an object, rather than a copy:
int i = 5;

bind(f, ref(i), _1);

bind(f, cref(42), _1);

boost::bind() creates many copies of the argument

That's by design.

To avoid it, avoid copies of the bind adaptor and use ref:

auto f = boost::bind(&foo, boost::ref(t));

  • Why does boost copy so many times?

Mostly due to the fact that your constructor cannot be elided. Keep it an aggregate or trivial constructor and it doesn't happen.

  • Is it correct to pass rvalue as an argument to bind (in both cases of implementation)?

Yes, bind captures arguments by value (unless you use explicit ref() or cref() to create reference_wrappers.)

  • Do I understand correctly that bind will move the object to its context and store it, and when foo is called, passes it as an lvalue reference?

Yes


Demo

Live On Coliru

#include <boost/bind.hpp>
#include <functional>
#include <iostream>

struct Test {
Test() { std::cout << "Create\n"; }
Test(const Test& /*unused*/) { std::cout << "Copy\n"; }
Test(Test&& /*unused*/) { std::cout << "Move\n"; }
~Test() noexcept { }
};

void foo(Test& /*unused*/) {}

int main() {
Test t;
auto f = boost::bind(&foo, boost::ref(t));
f();
}

Prints:

Create

boost::bind with functions that have parameters that are references

The boost documentation for bind suggests that you can use boost::ref and boost::cref for this.

Boost threads - passing parameters by reference

Bind copies its parameters. Use boost::ref:

boost::thread t(boost::bind(&SomeClass::OtherMethod,this, boost::ref(v))

Does boost::bind make a copy of a member function

According to my experiments (boost 1.49), boost::bind does not use dynamic memory for its own implementation. With this code

#include <boost/bind.hpp>

int f(int a , int b) {
return a>b ? a+b : a-b;
}

int main()
{
auto a = boost::bind(f, _1, 2);
return a(0);
}

I tried breaking on operator new variants in gdb and it didn't fire. So I suspect your problem is actually that boost::bind is making copies of either the bound arguments (compare the output of these two snippets) or the call arguments. Search for something among these that could allocate memory while copying, and try to get rid of it.

If you're using a C++11 compiler, you can get away with boost::bind completely and use a lambda function instead. The example would be transformed to

auto a = [&](int a1) { return f(a1, 2); }

That would only copy if you'd capture objects by value.

EDIT: With the code you posted, try changing the line in question to

TConstIterator pIt = std::find_if(rtContainer.begin(), rtContainer.end(), 
boost::bind(&TValueType::bSameSocket, boost::cref(rtData), _1));
^^^^^^^^^^^

That should make it better; report if it doesn't.

Why does boost::bind store arguments of the type passed in rather than of the type expected by the function?

There are different cases where you need the arguments to be processed at the call site.

The first such example is calling a member function, where you can either have the member called on a copy of the object (boost::bind( &std::vector<int>::push_back, myvector)) which most probably you don't want, or else you need to pass a pointer and the binder will dereference the pointer as needed (boost::bind( &std::vector<int>::push_back, &myvector )) --Note both options can make sense in different programs

Another important use case is passing an argument by reference to a function. bind will copy performing the equivalent to a pass-by-value call. The library offers the option of wrapping arguments through the helper functions ref and cref, both of which store a pointer to the actual object to be passed, and at the place of call they dereference the pointer (through an implicit conversion). If the conversion to the target type was performed at bind time, then this would be impossible to implement.

Does bind take value or reference of passed in non POD argument?

bind always takes it's arguments by value. This is one of the reasons why std::ref (and boost::ref) do exist.

Does copying a boost::function also copy the closure?

From what I can find (Judging from a cursory reading of the not exactly simple source and some experiments) it will copy the cloned object each time. It might be unnecessary in case of the function taking it's argument by const &, but in general the object might be mutated by the function. If the object is expensive to copy, wouldn't it make sense to capture it by reference (boost::ref or boost::cref come to mind) or, if the original object doesn't exist at the point of invocation, capture a boost::shared_ptr and write a adapter method, which unpacks the smartpointer and calls someFunction?

Edit: From experimentation not only will it copy construct that object whenever the boost::function is copied, but it will also copy several times inside boost::bind. I tested using the following code using boost 1.45 under mingw 32 with gcc 4.6 and -O2 ( and -std=c++0x):

struct foo_bar {
std::vector<int> data; //possibly expensive to copy
foo_bar()
{ std::cout<<"default foo_bar "<<std::endl; }
foo_bar(const foo_bar& b):data(b.data)
{ std::cout<<"copy foo_bar "<<&b<<" to "<<this<<std::endl; }
foo_bar& operator=(const foo_bar& b) {
this->data = b.data;
std::cout<<"asign foo_bar "<<&b<<" to "<<this<<std::endl;
return *this;
}
~foo_bar(){}
};

void func(const foo_bar& bar) { std::cout<<"func"<<std::endl;}

int main(int, char*[]) {
foo_bar fb;
boost::function<void()> f1(boost::bind(func, fb));
std::cout<<"Bind finished"<<std::endl;
boost::function<void()> f2(f1);
std::cout<<"copy finished"<<std::endl;
f1();
f2();
return 0;
}

The resulting output is as followed:

default foo_bar
copy foo_bar 0x28ff00 to 0x28ff10
copy foo_bar 0x28ff10 to 0x28ff28
copy foo_bar 0x28ff28 to 0x28ff1c
copy foo_bar 0x28ff1c to 0x28ff34
copy foo_bar 0x28ff34 to 0x28fed4
copy foo_bar 0x28fed4 to 0x28fee4
copy foo_bar 0x28fee4 to 0x28fef4
copy foo_bar 0x28fef4 to 0x28fe14
copy foo_bar 0x28fe14 to 0x28fe24
copy foo_bar 0x28fe24 to 0x28fe34
copy foo_bar 0x28fe34 to 0x6a2c7c
Bind finished
copy foo_bar 0x6a2c7c to 0x6a2c94
copy finished
func
func

So the copy constructor was called for the creation of f2 once and 11 times for the binding and assignment to f1. Since the first object is created on the stack and the addresses of the copies are very close to that and slightly increasing, it seems that the binding process goes through a lot of functions, which the compiler doesn't inline in this case and which each pass the object along by value. Using just boost::bind without saving the result anywhere:

int main(int, char*[]) {
foo_bar fb;
boost::function<void()> f1(boost::bind(func, fb));
return 0;
}

default foo_bar
copy foo_bar 0x28ff00 to 0x28ff10
copy foo_bar 0x28ff10 to 0x28ff28
copy foo_bar 0x28ff28 to 0x28ff1c
copy foo_bar 0x28ff1c to 0x28ff34
copy foo_bar 0x28ff34 to 0x28fef4

So five copies just to bind the object. So I would generaly avoid capturing anything which has at least moderate copy costs per value in any even remotely performance sensitive parts of the code. In comparison gccs std::tr1::bind and std::bind perform much better (in conjunction with std::tr1::function / std::function) (code is basically identical to the first testcode, just substitute boost:: with std::tr1:: respectively std:::

std::tr1::bind with std::tr1::function:
default foo_bar
copy foo_bar 0x28ff10 to 0x28ff28
copy foo_bar 0x28ff28 to 0x28ff34
copy foo_bar 0x28ff34 to 0x28ff04
copy foo_bar 0x28ff04 to 0x652c7c
Bind finished
copy foo_bar 0x652c7c to 0x652c94
copy finished
func
func

std::bind with std::function:
default foo_bar
copy foo_bar 0x28ff34 to 0x28ff28
copy foo_bar 0x28ff28 to 0x3c2c7c
Bind finished
copy foo_bar 0x3c2c7c to 0x3c2c94
copy finished
func
func

I assume std::bind either passes by const ref for internal invocations, or is written in a way which is more friendly to gccs inliner to inline some in and eliminate redundant copy constructors. tr1::bind still gets better optimized then boost::bind, but still far from optimal.

Of course as always with such a kind of tests YMMV with different compile flags/compilers

why is this program using boost::ref

boost::bind makes a copy of its inputs, so if boost::ref is not used in this case, a copy of the chat_message will be made. So it seems the authors of the code want to avoid that copy (at the cost of instantiating a boost::ref object or two). This could make sense if chat_message is large or expensive to copy. But it would make more sense to use a boost::cref, since the original is passed by const reference, and the call should not modify the passed message.

Note: the above applies to std::bind and std::tr1::bind.



Related Topics



Leave a reply



Submit