Boost logo

Boost :

Subject: Re: [boost] New libraries implementing C++11 features in C++03
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2011-11-23 20:17:36


On 11/23/2011 07:11 PM, Joel de Guzman wrote:
> On 11/24/2011 8:06 AM, Brent Spillner wrote:
>> On 23 Nov 2011 10:21:50 Joel de Guzman wrote:
>>> a good approximation of lambda is already existing in Boost. Namely: bind,
>>> lambda and phoenix. I posted a Spirit example of lambda in action using
>>> Phoenix:
>>>
>>> http://tinyurl.com/7w2h2r9
>>>
>>> Try as hard as you can, but you cannot ever come close to the clarity of
>>> he syntax presented there. Proponents of locals have cited error-messages
>>> generated by the compiler as a justification for Locals. Locals is probably
>>> a good workaround. But hear me out...
>>
>> First of all, this "trivial" example didn't even compile on the first
>> machine I tried it on, which had Boost 1.45 (which doesn't expose
>> qi:_val_type or qi:_1_type). This is a pretty good reminder of the
>
> Man! Of course you should use the examples in 1.45. Those examples
> are for 1.48 and uses new features implemented in 1.48! Sheesh!
>
>> On a machine with 1.48, the example compiles just fine. If you were
>> to pass std::string::iterators instead of const_iterators to
>> phrase_parse(), though ( a pretty common class of mistake in the real
>> world), you get this error message (GCC 4.4.4):
>>
>
> Double Sheesh! If you've spent even a few seconds looking into the
> error (beyond fault-finding), you will see that a simple textual
> search of "error" will reveal this:
>
>> ------------------- Horrific error messages follow ---------------------
>
> calc3.cpp:90: instantiated from here
> /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:176: error: no
> matching function for call to
> 'assertion_failed(mpl_::failed************
> (boost::spirit::qi::rule<Iterator, T1, T2, T3,
> T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const
> Expr&, mpl_::false_)
>
> [snip ... some complex types]
>
> ::error_invalid_expression::************)
>
> And double clicking on it using your editor will lead you here:
>
> static void define(rule& lhs, Expr const& expr, mpl::false_)
> {
> // Report invalid expression error as early as possible.
> // If you got an error_invalid_expression error message here,
> // then the expression (expr) is not a valid spirit qi expression.
> BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
> }
>
> If you've read the Spirit docs, you will know what that means.
>
> Now having said that, and before I leave this thread, let me remind
> everyone that **you can also have statement syntax in Phoenix** if you
> have a complex statement and you fear writing complex phoenix lambda
> expressions. It's called phoenix::functions.
>
> In fact here's what I advocate:
>
> 1) For simple 1-2-3 liners, use a phoenix lambda expression. It's hard
> to get them wrong. For example, you'll have to be absurdly dumb to
> get this wrong:
>
> auto plus = _1 + _2;
>
> 2) For more complex expressions, especially those involving statements,
> use a phoenix function plus a simple lambda expression that forwards
> to the phoenix function. Example:
>
> for_each(f, l, call_complex_function(_1));

Additionally, phoenix3 provides you with facilities to adapt already
existing functions (yes, even templates) and functors:
http://tinyurl.com/cg72pyy

> Regards,


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