boost::bind with references
I have a function defined as template<typename T> void foo(const T& x); and then I use boost::bind(foo, x); However, once the code is inside the body of foo, the addresses of x inside foo and the addresses of x when I called bind are different. So somehow a copy is being made. I can get around it by using boost::ref(), but is there a technical reason why it doesn't "just work" and pass it by reference?
AMDG Zachary Turner wrote:
I have a function defined as
template<typename T> void foo(const T& x);
and then I use boost::bind(foo, x);
However, once the code is inside the body of foo, the addresses of x inside foo and the addresses of x when I called bind are different. So somehow a copy is being made. I can get around it by using boost::ref(), but is there a technical reason why it doesn't "just work" and pass it by reference
Capturing by reference is more dangerous because it can leave dangling references. In Christ, Steven Watanabe
On Tue, Jun 30, 2009 at 8:57 PM, Steven Watanabe<watanabesj@gmail.com> wrote:
AMDG
Zachary Turner wrote:
I have a function defined as
template<typename T> void foo(const T& x);
and then I use boost::bind(foo, x);
However, once the code is inside the body of foo, the addresses of x inside foo and the addresses of x when I called bind are different. So somehow a copy is being made. I can get around it by using boost::ref(), but is there a technical reason why it doesn't "just work" and pass it by reference
Capturing by reference is more dangerous because it can leave dangling references.
Well, but what I mean is, shouldn't it pass it exactly according to how the function is specified? Or maybe there's just no way to do this. If the function is specified as taking a T& then I would expect it to pass by reference, whereas if the function is specified as taking a T, then I would expect it to pass by value. Currently it's passing by value even if the function is expecting a reference, which will almost never be the programmer's intention, and can introduce slicing among other things. Am I missing something? Zach
AMDG Zachary Turner wrote:
On Tue, Jun 30, 2009 at 8:57 PM, Steven Watanabe<watanabesj@gmail.com> wrote:
AMDG
Zachary Turner wrote:
I have a function defined as
template<typename T> void foo(const T& x);
and then I use boost::bind(foo, x);
However, once the code is inside the body of foo, the addresses of x inside foo and the addresses of x when I called bind are different. So somehow a copy is being made. I can get around it by using boost::ref(), but is there a technical reason why it doesn't "just work" and pass it by reference
Capturing by reference is more dangerous because it can leave dangling references.
Well, but what I mean is, shouldn't it pass it exactly according to how the function is specified? Or maybe there's just no way to do this. If the function is specified as taking a T& then I would expect it to pass by reference, whereas if the function is specified as taking a T, then I would expect it to pass by value. Currently it's passing by value even if the function is expecting a reference, which will almost never be the programmer's intention,
It's not a question of passing by value. bind is not exactly the same as an ordinary function call. bind creates a function object which stores copies of the arguments. Capturing them by value is the only safe default, since unlike in a function call, the copies or references can survive longer than the containing expression. Also, const T& is usually used in the same places where pass by value could be used. It is often okay to make a copy. Consider this case class C {}; void f(const C&) {} int main() { f(C()); // always safe. The temporary always outlives the reference boost::function<void()> x = bind(&f, C()); // not safe if bind captures by reference. }
and can introduce slicing among other things. Am I missing something?
bind doesn't try to figure out what to do based on the function signature. In general it is not possible. How should bind capture its arguments for: struct F { typedef void result_type; template<class T> void operator()(const T&) const {} }; In Christ, Steven Watanabe
2009/6/30 Zachary Turner <divisortheory@gmail.com>:
However, once the code is inside the body of foo, the addresses of x inside foo and the addresses of x when I called bind are different. So somehow a copy is being made. I can get around it by using boost::ref(), but is there a technical reason why it doesn't "just work" and pass it by reference?
Well there's no way to tell that it's a reference, so it has to pick one or the other. Presumably it chose by-value for default to match function argument passing.
participants (3)
-
Scott McMurray
-
Steven Watanabe
-
Zachary Turner