Boost logo

Boost :

Subject: Re: [boost] [local] Help for the Alternatives section
From: lcaminiti (lorcaminiti_at_[hidden])
Date: 2011-05-12 15:05:27


Jeffrey Lee Hellrung, Jr.-2 wrote:
>
> On Thu, May 12, 2011 at 11:16 AM, lcaminiti <lorcaminiti_at_[hidden]>
> wrote:
>
>>
>> Jeffrey Lee Hellrung, Jr.-2 wrote:
>>
> [...]
>
>> > I would infer from this and the documentation that
>> >
>> > const bind(const int&) factor // outer const superfluous???
>> > bind(const int&) factor
>> > const bind(const int)& factor // outer const superfluous???
>> > bind(const int)& factor
>> > const bind(int)& factor
>> > bind(const int&) const factor // outer const superfluous???
>> > bind(int) const & factor
>> >
>> > are all equivalent, but I'm not sure. Can you please clarify in the
>> > documentation?
>> >
>> > [...snip rest of example...]
>> >
>>
>> Yes, the Tutorial section already mentions that:
>> 1) const must always appear before bind when constant binding is used so
>> bind ... const is not valid (this is just for simplicity, the macros
>> could
>> be programmed to accepts both const bind and bind const).
>> 2) when const bind is used on a variable that is already const the bind's
>> const has no effect.
>>
>
> So that addresses the placement of const; the '&' can also either be put
> inside or outside the bind(...), right?
>

No. References are bound be value when bind is used without the trailing &:

int y = 0;
int& x = y
BOOST_LOCAL_BLOCK(bind x) { // by val
    x = 0; // Has only local effect (outer x and y are not changed).
}
BOOST_LOCAL_BLOCK(bind& x) { // by ref
    x = 0; // Has effect on enclosing scope (outer x and y are changed).
}

This is how Boost.ScopeExit bind semantic works and it made sense to me
because it allows to bind references by both value and reference (and not
just by reference). I can spell this out more clearly in the docs.

OTOH, const is never stripped by bind because if a variable is const in the
enclosing scope, programmers would expect it to be always const also in at
local scopes:

const int x = 10;
BOOST_LOCAL_BLOCK(bind& x) { // (1) by const&
    x = -1; // This should always error even when const bind was not used.
}
BOOST_LOCAL_BLOCK(const bind& x) { // (2) also by const& (equivalent to
above)
    x = -1; // Also error.
}

Of course Boost.Local could strip the const in case (1) (using const_cast)
but I would find it confusing that a const is no longer const because it is
not bind by constant.

> Also, what about commas from template instantiations? E.g., does
>
> bind(tmpl<T1,T2>) x
>
> work?
>

Yes but you have to use BOOST_IDENTITY_TYPE (its a macro of Boost.Local that
I'd eventually propose to add to under boost/utility). It's explained in the
Advanced Topics section:

http://svn.boost.org/svn/boost/sandbox/local/libs/local/doc/html/boost_local/Advanced_Topics.html#boost_local.Advanced_Topics.commas_and_symbols_in_macro_parameters

For example:

bind(BOOST_IDENTITY_TYPE((std::map<std::string, double>))) x

This works (on ISO C++, no variadics required). Note the extra set of
parenthesis needed around the type-with-commas within the macro parenthesis
BOOST_IDENTITY_TYPE((type_with_commas)) -- it expands to something like
function_traits<void(type_with_commas)>::arg1_type.

--Lorenzo

--
View this message in context: http://boost.2283326.n4.nabble.com/local-Help-for-the-Alternatives-section-tp3408469p3518430.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