c++boostfusion

Boost.Fusion define struct array member


How do you do it?

using char10 = char[10];  
BOOST_FUSION_DEFINE_STRUCT(
    (demo), employee,
    (char10, name))

doesn't work:
main.cpp:8:1: error: incompatible types in assignment of 'boost::call_traits::param_type {aka const char* const}' to 'char10 {aka char [10]}'

using char10 = char[10];
BOOST_FUSION_DEFINE_STRUCT(
    (demo), employee,
    (decltype(char10{}), name))

doesn't work either:
main.cpp:8:1: error: value-initialization of reference type 'char (&)[10]'


Solution

  • That's not possible for C-style arrays because of the infamous array-to-pointer-decay property that C has (and still binds C++ for backwards compatibility).

    This breaks, since the Fusion macro generates code like:

    namespace demo {
        struct employee {
            typedef employee self_type;
            char10 name;
            employee() : name() {}
            employee(self_type const &) = default;
            employee(self_type &&) = default;
            template <typename Seq>
                employee(Seq const &seq, typename boost::disable_if<boost::is_convertible<Seq const &, char10> >::type * = 0)
                : name(boost::fusion::deref(boost::fusion::advance_c<0>(boost::fusion::begin(seq)))) {}
            self_type &operator=(self_type const &) = default;
            self_type &operator=(self_type &&) = default;
            template <typename Seq> self_type &operator=(Seq const &seq) {
                typedef typename boost::fusion::result_of::begin<Seq const>::type I0;
                I0 i0 = boost::fusion::begin(seq);
                name = boost::fusion::deref(i0);
                return *this;
            }
            explicit employee(boost::call_traits<char10>::param_type arg) : name(arg) {}
        };
    } // namespace demo
    

    In the constructor's initializer list:

    explicit employee(boost::call_traits<char10>::param_type arg) : name(arg) {}
    

    the type of arg will be char const* which is not a valid initializer for the string (a char const(&)[10] would be, but would need

    Solution

    Go the C++ way:

    Live On Coliru (c++11)

    #include <boost/fusion/include/define_struct.hpp>
    
    using char10 = std::array<char, 10>;
    
    BOOST_FUSION_DEFINE_STRUCT(
        (demo), employee,
        (char10, name))
    
    #include <boost/core/demangle.hpp>
    #include <iostream>
    int main() {
        demo::employee emp;
        emp.name = {{'I',' ','a','m',' ','G','r','o','o','t'}};
    }
    

    If you're stuck in the dark ages, you can use boost::array instead:

    Live On Coliru (c++03)