Subject: Re: [Boost-bugs] [Boost C++ Libraries] #2429: raw[] attribute incompatibility
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-06-02 01:32:48
#2429: raw[] attribute incompatibility
------------------------------------------+---------------------------------
Reporter: vallentin_at_[hidden] | Owner: djowel
Type: Bugs | Status: closed
Milestone: Boost 1.37.0 | Component: spirit
Version: Boost 1.36.0 | Severity: Problem
Resolution: invalid | Keywords: raw, attribute, compatibility
------------------------------------------+---------------------------------
Changes (by hkaiser):
* status: new => closed
* resolution: => invalid
Comment:
Replying to [ticket:2429 vallentin_at_[hidden]]:
> I discovered an issue with the raw[] parser returning an
iterator_range<T>.
> While it should be compatible to std::string, it is not according to my
> experience. Below, I attached an excerpt from the mailing list that
captures the
> problem pretty well.
>
> On Tue, Oct 21, 2008 at 09:04:48AM +0800, Joel de Guzman wrote:
> > First, std::string should be compatible with iterator pair, so it
should
> > just be:
> >
> > raw["foo"][_val = _1]
>
> This was in fact my first choice but did not compile with several g++
> versions [1]:
This doesn't compile, and rightly so. _1 has the type iterator_range<> and
_val has the type string. Since there is no assignment operator allowing
to do this conversion, the compilation must fail. Everything ok so far.
> > Or simply:
> >
> > r %= raw["foo"];
>
> Unlike the explicit above version, this works. This primarily drives my
> confusion. However, in my more complex grammar I cannot use this
> convenient approach.
This must compile (and as you've seen, it does). The reason is, that the
raw[] directive is able to store it's attribute in any type 'compatible'
compatible with an iterator_range<>. That means it can store it's
attribute in any type having a similar constructor as iterator_range (or
otherwise similar conversion operators). As string has a constructor
taking two iterators (as iterator_range<> does) the code above compiles
and works fine.
> > But, if you really need to get at the first/last, since
> boost::iterator_range
> > is a valid STL sequence, you can simply use:
> >
> > construct<std::string>(begin(_1),end(_1))
> >
> > begin and end are phoenix functions in the stl/container module.
>
> Interestingly replacing boost::phoenix::at_c<0>(_1) with begin(_1) /
> end(_1) works and compiles.
Remember spirit::arg_names::_1 is not the same as phoenix::_1. I hope this
answers your question.
Regards Hartmut
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/2429#comment:1> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:00 UTC