S
SG
Hello World!
Since the standardization committee accepts proposals for C++1y and
the lack of a "move capture" for lambdas always bugged me, I thought I
should start asking about opinions regarding the importance of such a
feature and a possible syntax. Maybe this will result in a
proposal ...
Background:
Move semantics is basically an optimization of copying by exploiting
that in some situations modifications of the source are safe since
nobody cares about the source anymore and/or there is no other way of
accessing the source a second time. Example:
string foo = "hello";
vector<string> blah;
// move(foo) means "i don't care anymore about foo"
blah.push_back(move(foo));
// foo will probably be an empty string at this point
// (depending on the implementation)
Lambda objects can carry a "state". Variables can be captured by value
and by reference which means that the lambda object will either store
the named object directly as a copy or just a reference to it.
Example:
int a = 23;
int b = 42;
[&a,b]()mutable{++a;++b;}();
cout << a << ' ' << b << endl;
// output: 24 42 since b in the lambda's body is just a copy
Since there is a special capture syntax -- see [&a,b] above -- one
might ask: What do I need to do if I want to move (not copy) something
into the lambda? Unfortunately, this is currently not possible. But it
could be useful for function objects, that outlive their scope and
need to remember things that are costly or even impossible to copy but
fast to move.
What about a possible syntax? I saw [&&b] being proposed but I'd argue
against it because && has little to do with a move request, it's an
rvalue reference declarator. But the lambda object is not supposed to
store an rvalue reference as member but something "by value" only that
this is initialized with an rvalue. Other ideas:
* [-b] // "subtract" b from current scope
* [move b] // move as conditional keyword, very explicit
I'm open to other suggestions. The next thing one should worry about
is probably the default capture. Does it make sense to offer a "move
capture default"? Or would this be a bad idea due to possible pit
falls? I'm not sure. I'd prefer to be explicit about what objects to
move around to avoid accidental moves.
Comments are welcome!
SG
Since the standardization committee accepts proposals for C++1y and
the lack of a "move capture" for lambdas always bugged me, I thought I
should start asking about opinions regarding the importance of such a
feature and a possible syntax. Maybe this will result in a
proposal ...
Background:
Move semantics is basically an optimization of copying by exploiting
that in some situations modifications of the source are safe since
nobody cares about the source anymore and/or there is no other way of
accessing the source a second time. Example:
string foo = "hello";
vector<string> blah;
// move(foo) means "i don't care anymore about foo"
blah.push_back(move(foo));
// foo will probably be an empty string at this point
// (depending on the implementation)
Lambda objects can carry a "state". Variables can be captured by value
and by reference which means that the lambda object will either store
the named object directly as a copy or just a reference to it.
Example:
int a = 23;
int b = 42;
[&a,b]()mutable{++a;++b;}();
cout << a << ' ' << b << endl;
// output: 24 42 since b in the lambda's body is just a copy
Since there is a special capture syntax -- see [&a,b] above -- one
might ask: What do I need to do if I want to move (not copy) something
into the lambda? Unfortunately, this is currently not possible. But it
could be useful for function objects, that outlive their scope and
need to remember things that are costly or even impossible to copy but
fast to move.
What about a possible syntax? I saw [&&b] being proposed but I'd argue
against it because && has little to do with a move request, it's an
rvalue reference declarator. But the lambda object is not supposed to
store an rvalue reference as member but something "by value" only that
this is initialized with an rvalue. Other ideas:
* [-b] // "subtract" b from current scope
* [move b] // move as conditional keyword, very explicit
I'm open to other suggestions. The next thing one should worry about
is probably the default capture. Does it make sense to offer a "move
capture default"? Or would this be a bad idea due to possible pit
falls? I'm not sure. I'd prefer to be explicit about what objects to
move around to avoid accidental moves.
Comments are welcome!
SG