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
    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:

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


View this message in context:
Sent from the Boost - Dev mailing list archive at

Boost list run by bdawes at, gregod at, cpdaniel at, john at