I'm stuck reading the description of std::bind
in N3225, in subsection 20.8.10.1
. It says the following should print 1
, but I thought that bind
is supposed to copy its arguments and therefor it should print 0
. If one wants to refer to the passed argument, one needs to use std::ref
, right?
void f(int &a) { a = 1; }
int main() {
int a = 0;
std::bind(f, a)();
std::cout << a << std::endl;
}
GCC outputs 0
, agreeing with what I thought things work. But N3225 says that std::bind(f, a1)
shall return a call wrapper that when called by wrapper()
will call INVOKE(f, v1)
, where v1
shall be a
(the argument I passed in, in other words, using binds
's incoming parameter which is a perfect forwarding parameter, std::forward<A1>(a1)
).
INVOKE(f, a)
is defined by 20.8.2 to f(a)
. So, this defines that the call to the returned call wrapper passes the original argument. What am I missing?
Wow, this is confusing beyond belief. It defines v1
as tid
and it as the following (ti
is the i-th perfect forwarding bind parameter, and TiD
is the decayed type of that parameter - i.e an array becomes a pointer etc).
tid
is an lvalue of typeTiD
constructed fromstd::forward<Ti>(ti)
Alright, I did say, this tid
is std::forward<Ti>(ti)
and it's an lvalue! But this is not what it really means to say. It means
tid
is an lvalue of typeTiD
that refers to an object constructed fromstd::forward<Ti>(ti)
It makes much more sense now. Because what if std::forward<Ti>(ti)
is actually an rvalue? The "lvalue ... constructed from ..." is meant to mean that we create a new object from "..." and make the lvalue refer to it.