|
Boost : |
Subject: Re: [boost] New libraries implementing C++11 features in C++03
From: Joel de Guzman (joel_at_[hidden])
Date: 2011-11-23 20:11:19
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));
Regards,
-- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk