#include <iostream>
using namespace std;
template < typename Fn>
void call_value( Fn f) { f( ) ; }
template < typename Fn>
void call_ref( Fn & f) { f( ) ; }
template < typename Fn>
void call_cref( Fn const & f) { f( ) ; }
struct Data {
Data( ) { }
Data( Data const & ) {
cout << "copy" << endl;
}
Data( Data && ) {
cout << "move" << endl;
}
} ;
int main( int , char ** ) {
Data data;
auto capref = [ & data] ( ) { } ;
cout << "capture by value, so we get a " ;
auto capcp = [ data] ( ) { } ;
cout << " the lambda with a reference ... " ;
call_value( capref) ;
cout << " could now be called and mutate .. " ;
call_ref( capref) ;
call_cref( capref) ;
cout << " but won't, as it had to be declared mutable " << endl;
cout << "the lambda with an instance: " ;
call_value( capcp) ;
cout << "but not " ;
call_ref( capcp) ;
call_cref( capcp) ;
cout << " the reference versions " << endl;
bool en = false ;
auto trigger = [ en] ( bool enable = true ) mutable {
if ( en) {
cout << "fire!" << endl;
}
if ( en or enable) {
en = true ;
}
} ;
cout << "won't shoot" << endl;
trigger( false ) ;
call_value( trigger) ;
trigger( false ) ;
call_ref( trigger) ;
cout << "and now ... " ;
trigger( false ) ;
// const ref won't work
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8dHlwZW5hbWUgRm4+CnZvaWQgY2FsbF92YWx1ZShGbiBmKSB7IGYoKTsgfQp0ZW1wbGF0ZTx0eXBlbmFtZSBGbj4Kdm9pZCBjYWxsX3JlZihGbiAmIGYpIHsgZigpOyB9CnRlbXBsYXRlPHR5cGVuYW1lIEZuPgp2b2lkIGNhbGxfY3JlZihGbiBjb25zdCAmIGYpIHsgZigpOyB9CgpzdHJ1Y3QgRGF0YSB7CiAgRGF0YSgpIHt9CiAgRGF0YShEYXRhIGNvbnN0ICYpIHsKICAgIGNvdXQgPDwgImNvcHkiIDw8IGVuZGw7CiAgfQogIERhdGEoRGF0YSAmJikgewogICAgY291dCA8PCAibW92ZSIgPDwgZW5kbDsKICB9Cn07CgppbnQgbWFpbihpbnQsIGNoYXIgKiopIHsKICBEYXRhIGRhdGE7CgogIGF1dG8gY2FwcmVmID0gWyZkYXRhXSAoKSB7fTsKICBjb3V0IDw8ICJjYXB0dXJlIGJ5IHZhbHVlLCBzbyB3ZSBnZXQgYSAiOwogIGF1dG8gY2FwY3AgPSBbZGF0YV0gKCkge307CgogIGNvdXQgPDwgIiB0aGUgbGFtYmRhIHdpdGggYSByZWZlcmVuY2UgLi4uICI7CiAgY2FsbF92YWx1ZShjYXByZWYpOwogIGNvdXQgPDwgIiBjb3VsZCBub3cgYmUgY2FsbGVkIGFuZCBtdXRhdGUgLi4gIjsKICBjYWxsX3JlZihjYXByZWYpOwogIGNhbGxfY3JlZihjYXByZWYpOwogIGNvdXQgPDwgIiBidXQgd29uJ3QsIGFzIGl0IGhhZCB0byBiZSBkZWNsYXJlZCBtdXRhYmxlICIgPDwgZW5kbDsKCiAgY291dCA8PCAidGhlIGxhbWJkYSB3aXRoIGFuIGluc3RhbmNlOiAiOwogIGNhbGxfdmFsdWUoY2FwY3ApOwogIGNvdXQgPDwgImJ1dCBub3QgIjsKICBjYWxsX3JlZihjYXBjcCk7CiAgY2FsbF9jcmVmKGNhcGNwKTsKICBjb3V0IDw8ICIgdGhlIHJlZmVyZW5jZSB2ZXJzaW9ucyAiIDw8IGVuZGw7CgogIGJvb2wgZW4gPSBmYWxzZTsKICBhdXRvIHRyaWdnZXIgPSBbZW5dKGJvb2wgZW5hYmxlID0gdHJ1ZSkgbXV0YWJsZSB7CiAgICBpZiAoZW4pIHsKICAgICAgY291dCA8PCAiZmlyZSEiIDw8IGVuZGw7CiAgICB9CiAgICBpZiAoZW4gb3IgZW5hYmxlKSB7CiAgICAgIGVuID0gdHJ1ZTsKICAgIH0KICB9OwogIGNvdXQgPDwgIndvbid0IHNob290IiA8PCBlbmRsOwogIHRyaWdnZXIoZmFsc2UpOwogIGNhbGxfdmFsdWUodHJpZ2dlcik7CiAgdHJpZ2dlcihmYWxzZSk7CiAgY2FsbF9yZWYodHJpZ2dlcik7CiAgY291dCA8PCAiYW5kIG5vdyAuLi4gIjsKICB0cmlnZ2VyKGZhbHNlKTsKICAvLyBjb25zdCByZWYgd29uJ3Qgd29yawogIHJldHVybiAwOwp9