Boost logo

Boost :

Subject: Re: [boost] [scope_exit] can MSVC lambdas capture data members?
From: lcaminiti (lorcaminiti_at_[hidden])
Date: 2012-03-15 15:21:56


Alexander Nasonov wrote
>
> lcaminiti wrote:
>>
>> Nathan Ridge wrote
>> >
>> > GCC 4.5 is in error to allow that. 4.7 does not allow it.
>> >
>> > The correct way to use a data member in the lambda is to capture
>> "this",
>> > and then
>> > access the member via "this->member" inside the lambda.
>> >
>
> If the above it true ...
>
>> Works with the current implementation of ScopeExit that does not use
>> lambdas
>> but it will no longer compile with the implementation of ScopeExit that
>> uses
>> lambdas. Therefore, the lambda implementation of ScopeExit cannot be
>> backward compatible... I will discuss this issue with ScopeExit's main
>> author Alexander Nasonov but this might mean that ScopeExit will never be
>> implemented internally using lambdas, not even on C++11 compilers.
>
> then don't claim backward-compatibility and make sure that lambda
> implementation can't be implicitly enabled (only if a user defines
> BOOST_SCOPE_EXIT_USE_LAMBDAS or something like this).
>

1) I'd propose to never implement BOOST_SCOPE_EXIT using lambdas. There is
no advantage for the user in the lambda implementation because I already
extended BOOST_SCOPE_EXIT to use variadic macros, capture the object
`this_`, and capture no variable (using `void`) all of which without using
C++11 and maintaining backward compatibility with the existing
BOOST_SCOPE_EXIT syntax.

// On all compilers (it never uses C++11 lambdas).
BOOST_SCOPE_EXIT(&commit, &persons_) {
    if(!commit) persons_.pop_back();
} BOOST_SCOPE_EXIT_END

2) However, I'd leave BOOST_SCOPE_EXIT_ALL because it allows for implicit
captures using `&` and `=`. This macro uses C++11 lambdas and it is #defined
only for C++11 compilers. BOOST_SCOPE_EXIT_ALL and BOOST_SCOPE_EXIT will
therefore have different capture semantics (e.g., BOOST_SCOPE_EXIT_ALL
cannot capture data members without capturing `this` while BOOST_SCOPE_EXIT
can) but if users find that confusing they just don't use SCOPE_EXIT_ALL.

// Only on C++11 compilers (same capture semantics of C++11 lambda and
therefore different from BOOST_SCOPE_EXIT).
BOOST_SCOPE_EXIT_ALL(&, this) {
    if(!commit) persons_.pop_back();
}; // Use `;` instead of BOOST_SCOPE_EXIT_END

3) Finally, if you #define BOOST_SCOPE_EXIT_CONFIG_NO_CXX11 (or shall this
be NO_CPP11? ;) ) then BOOST_SCOPE_EXIT_ALL is never defined not even on
C++11 compilers.

This way the user is always in control and he/she gets the extra benefits of
implicit lambda captures when they apply. What do you think?

Thanks.
--Lorenzo

--
View this message in context: http://boost.2283326.n4.nabble.com/boost-scope-exit-can-MSVC-lambdas-capture-data-members-tp4472788p4476097.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk