Re: Using Tuple and bind in Spirit causes compiler error

Juan Dent <[email protected]> Sun, 25 Oct 2020 18:01:58 +0000
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <PH0PR10MB45820097414FE7006A3F24389B180@PH0PR10MB4582.namprd10.prod.outlook.com>
Where do I add your code Larry?

And do I only add this?

---------------------------------------------------------------
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> >;
};
------------------------------------------------------------------

I get an error:
1>C:\vcpkg\installed\x64-windows\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>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>'
1>C:\vcpkg\installed\x64-windows\include\boost/spirit/home/qi/detail/assign_to.hpp(171,13): message : in instantiation of function template specialization 'boost::spirit::traits::assign_to_attribute_from_value<boost::tuples::tuple<boost::optional<double>, boost::optional<int>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, boost::fusion::vector<boost::optional<double>, boost::optional<int> >, void>::call<boost::fusion::vector<boost::optional<double>, boost::optional<int> > >' requested here
1>C:\vcpkg\installed\x64-windows\include\boost/spirit/home/qi/detail/assign_to.hpp(370,59): message : in instantiation of member function 'boost::spirit::traits::assign_to_attribute_from_value<boost::tuples::tuple<boost::optional<double>, boost::optional<int>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>, boost::fusion::vector<boost::optional<double>, boost::optional<int> >, void>::call' requested here
1>C:\vcpkg\installed\x64-windows\include\boost/spirit/home/qi/detail/assign_to.hpp(393,17): message : in instantiation of function template specialization 'boost::spirit::traits::detail::assign_to<boost::fusion::vector<boost::optional<double>, boost::optional<int> >, boost::tuples::tuple<boost::optional<double>, boost::optional<int>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >' requested here
1>C:\vcpkg\installed\x64-windows\include\boost/spirit/home/qi/detail/attributes.hpp(27,21): message : in instantiation of function template specialization 'boost::spirit::traits::assign_to<boost::fusion::vector<boost::optional<double>, boost::optional<int> >, boost::tuples::tuple<boost::optional<double>, boost::optional<int>, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >' requested here

Thanks Larry,
Juan Dent

-----Original Message-----
From: Larry Evans <[email protected]> 
Sent: Sunday, October 25, 2020 10:56 AM
To: [email protected]
Subject: Re: [Spirit-general] Using Tuple and bind in Spirit causes compiler error

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://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fboostorg%2Fspirit%2Fblob%2Fmaster%2Finclude%2Fboost%2Fspirit%2Fhome%2Fqi%2Faction%2Faction.hpp%23L57&amp;data=04%7C01%7C%7C8f37406e3fa647ccc79808d87906fae8%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637392418173430250%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=POwl48RGMU%2B7WvH0mY%2BHQHYvhUb%2BHQlrkj%2FXVCg%2F8j0%3D&amp;reserved=0

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




_______________________________________________
Spirit-general mailing list
[email protected]
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.sourceforge.net%2Flists%2Flistinfo%2Fspirit-general&amp;data=04%7C01%7C%7C8f37406e3fa647ccc79808d87906fae8%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637392418173430250%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MazjdH5TPm6h7SsYlfpBHhaa4FFwLCqiyn1hWwEEASM%3D&amp;reserved=0