Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost fusion and boost qi - compile-time error

Tags:

c++

boost

I am unable to compile the following code:

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>

#include <string>

struct function
{
  std::string ret_type;
  std::string name;
};

BOOST_FUSION_ADAPT_STRUCT(
  function,
  (std::string, ret_type)
  (std::string, name)
)

int main() {}

MSVC-11.0 with boost 1.54 gives me the following errors:

1>main.cpp(6084): error C3203: 'function' : unspecialized class template can't be used as a template argument for template parameter 'Sequence', expected a real type
1>main.cpp(6084): error C2955: 'boost::function' : use of class template requires template argument list
1>          e:\libs\boost_1_54_0\boost\function\function_fwd.hpp(33) : see declaration of 'boost::function'
1>main.cpp(6084): error C2913: explicit specialization; 'boost::fusion::traits::tag_of' is not a specialization of a class template
1>main.cpp(6084): error C3203: 'function' : unspecialized class template can't be used as a template argument for template parameter 'Seq', expected a real type
1>          e:\libs\boost_1_54_0\boost\function\function_fwd.hpp(33) : see declaration of 'boost::function'
1>main.cpp(6084): error C2913: explicit specialization; 'boost::fusion::extension::access::struct_member' is not a specialization of a class template
1>          e:\libs\boost_1_54_0\boost\function\function_fwd.hpp(33) : see declaration of 'boost::function'
1>main.cpp(6084): error C2913: explicit specialization; 'boost::fusion::extension::struct_member_name' is not a specialization of a class template
1>          e:\libs\boost_1_54_0\boost\function\function_fwd.hpp(33) : see declaration of 'boost::function'
1>main.cpp(6084): error C2913: explicit specialization; 'boost::fusion::extension::struct_size' is not a specialization of a class template
1>          e:\libs\boost_1_54_0\boost\function\function_fwd.hpp(33) : see declaration of 'boost::function'
1>main.cpp(6084): error C2913: explicit specialization; 'boost::fusion::extension::struct_is_view' is not a specialization of a class template
1>          e:\libs\boost_1_54_0\boost\function\function_fwd.hpp(33) : see declaration of 'boost::function'
1>main.cpp(6084): error C2913: explicit specialization; 'boost::mpl::sequence_tag' is not a specialization of a class template

Everything is fine if I remove the "boost/spirit/include/qi.hpp" including or explicitly tells that function structure is placed inside global namespace:

BOOST_FUSION_ADAPT_STRUCT(
  ::function,
  (std::string, ret_type)
  (std::string, name)
)
like image 207
FrozenHeart Avatar asked Mar 21 '23 16:03

FrozenHeart


2 Answers

When you use the BOOST_FUSION_ADAPT_STRUCT macro, it creates some types and places them inside the boost namespace. The definition of those types will reference the struct name that you gave it.

In your case, you gave the struct a name which is the same as a name already existing in the boost namespace: boost::function, which is apparently indirectly included by the boost qi header. Since the generated code is in the boost namespace, it thinks you meant to refer to boost::function rather than to your type ::function.

For this reason, the documentation says: "struct_name should be the fully namespace qualified name of the struct to be adapted". So your solution of adding the global namespace qualifier :: before the type name is correct.

like image 152
interjay Avatar answered Mar 23 '23 05:03

interjay


There is somehting inside the macro scope of boost fusion that is called function, and it seems that it has priority over your type. It works if you change the name of your struct :

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>

#include <string>

struct my_function
{
  std::string ret_type;
  std::string name;
};

BOOST_FUSION_ADAPT_STRUCT(
  my_function,
  (std::string, ret_type)
  (std::string, name)
)

int main() {}
like image 26
Drax Avatar answered Mar 23 '23 07:03

Drax