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