Question

How can I make the following Boost Fusion struct?

#include <array>
#include <boost/fusion/include/define_struct_inline.hpp>

BOOST_FUSION_DEFINE_STRUCT_INLINE(
  MyStruct,
  (std::array<int, 3>, foo)
)

This fails to compile (GCC 4.8.1 and Boost 1.53) because std::array<int, 3> is interpreted as 2 arguments instead of 1.

Note that I am NOT asking about the special case shown above (it's just an example). This particular problem has the trivial solution of just using typedef std::array<int, 3> Int3Array;.

I am asking about the general problem of using types with multiple template arguments separated by commas as a type in the list of fields of a Boost Fusion struct. Eventually, I want to use a template Boost Fusion struct where I cannot define typedefs in advance. For example, I might want to do something like this:

BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE(
  (A)(B)(C),
  MyAdvancedStruct,
  (A<B, C>, bar)
)
Was it helpful?

Solution

A workaround that works could be

BOOST_FUSION_DEFINE_STRUCT_INLINE(
  MyStruct,
  (decltype(std::array<int, 3>()), foo)
)

Of course to make it /generally/ applicable

BOOST_FUSION_DEFINE_STRUCT_INLINE(
MyStruct,
(boost::remove_reference<decltype(std::declval<std::array<int, 3>>())>::type, foo)
)

Which seems to call for another macro... but, oh wait :) BOOST_PP_COMMA seems the better choice.

Proof of concept: http://coliru.stacked-crooked.com/a/f8b407b810fcfdc0

OTHER TIPS

If you can't use a typedef or using declaration, try using Boost.IdentityType like this:

#include <array>
#include <boost/fusion/include/define_struct_inline.hpp>
#include <boost/utility/identity_type.hpp>

BOOST_FUSION_DEFINE_STRUCT_INLINE(
  MyStruct,
  (typename BOOST_IDENTITY_TYPE((std::array<int, 3>)), foo)
)

int main()
{
    MyStruct x;
    static_assert(boost::is_same<decltype(x.foo), std::array<int, 3> >::value, "yup");
}

See Coliru live demo.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top