Re: Using Tuple and bind in Spirit causes compiler error
Larry Evans <[email protected]> Sun, 25 Oct 2020 11:55:55 -0500
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
On 10/23/20 8:49 PM, Joel de Guzman wrote:
> On 10/24/20 1:50 am, Juan Dent wrote:
>> Hi,
>>
>> I produced a MVCE with the error at compile time (see line 22 of
>> MVCE.cpp). REMOVING the semantic action deletes the compiler error!
>> The source is as follows:
>> -------------------------------------------------------------------------------------------------------------------------------------
>>
>
> If you use clang or g++, this is the error that you will get:
>
> /usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:153:20:
> error: no matching conversion for static_cast from 'const
> boost::fusion::vector<boost::optional<double>, boost::optional<int> >'
> to 'boost::tuples::tuple<boost::optional<double>, boost::optional<int>,
> ...>'
>
> Why is that happening? If you are using semantic actions, the semantic
> action **WILL**
> synthesize a suitable attribute for you. In this case, the synthesized
> attribute is
> a boost::fusion::vector which **IS NOT*** assignable to a boost::tuple.
>
> Suggestion 1: Avoid mixing semantic actions with attributes, unless you
> really know
> what you are doing and already gained more proficiency with Spirit. In
> most cases,
> you can live without semantic actions.
>
>
> Suggestion 2: Try other compilers. Error messages generated by Visual
> Studio are
> often tough to decipher.
>
> Regards,
Suggestion 3: Use transform_attribute:
https://github.com/boostorg/spirit/blob/master/include/boost/spirit/home/qi/action/action.hpp#L57
where the transform_attribute is:
namespace boost { namespace spirit { namespace traits
{
template<>
struct transform_attribute
< which_attribute<tag_tuple>::type
, which_attribute<tag_vector>::type
, qi::domain
>
{
typedef which_attribute<tag_vector>::type type;
typedef which_attribute<tag_tuple>::type orig_type;
static type pre(orig_type& ot)
{ std::cout<<"transform_attribute::pre\n";
return type{};
}
static void post(orig_type& ot, type& t)
{ std::cout<<"transform_attribute::post\n";
at_c<0>(ot)=at_c<0>(t);
at_c<1>(ot)=at_c<1>(t);
}
static void fail(orig_type&) {}
};
}}}
and where which_attribute is:
enum tag_attribute
{ tag_tuple
, tag_vector
};
template<tag_attribute TagAttribute=tag_vector>
struct which_attribute
{
using type=fusion::vector<optional<double>, optional<int> >;
};
template<>
struct which_attribute<tag_tuple>
{
using type=boost::tuple<optional<double>, optional<int> >;
};
Regards,
Larry