Search code examples
c++templatesboost-fusionboost-hana

Define Hana struct with template parameters


Is there a way to define(adapt) a struct for Hana that has template parameters?

The canonical example is a non-template class,

#include <boost/hana/define_struct.hpp>
#include <string>

namespace hana = boost::hana;

struct Person {
    BOOST_HANA_DEFINE_STRUCT(Person,
        (std::string, name),
        (int, age)
    );
};

We I try to add template parameters there is a compilation error:

template<class S = std::string, class I = int>
struct Person {
    BOOST_HANA_DEFINE_STRUCT(Person<S, I>,
        (S, name),
        (I, age)
    );
};

I though that this failed because of the use of commas, so I tried decltype(Person<S, I>) in place of Person<S,I>.

In Boost.Fusion we had BOOST_FUSION_DEFINE_TPL_STRUCT, but I can't find the equivalent in Hana.

How can I define a Hana Struct with template parameters?


Solution

  • I found the solution here: https://boostorg.github.io/hana/group__group-Struct.html

    template<class S, class I>
    struct Person {
        S name;
        I age;
    
        struct hana_accessors_impl {
            static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
                return boost::hana::make_tuple(
                    boost::hana::make_pair(BOOST_HANA_STRING("name"),
                    [](auto&& p) -> decltype(auto) {
                        return boost::hana::id(std::forward<decltype(p)>(p).name);
                    }),
                    boost::hana::make_pair(BOOST_HANA_STRING("age"),
                    [](auto&& p) -> decltype(auto) {
                        return boost::hana::id(std::forward<decltype(p)>(p).age);
                    })
                );
            }
        };
    };
    

    Which raises other question, why does Hana need the first parameter at all? since it is not necessary?

    BTW, this also worked, which is something I didn't try to begin with. I am not sure if it works in general.

    template<class S, class I>
    struct Person {
        BOOST_HANA_DEFINE_STRUCT(Person,
            (std::string, name),
            (int, age)
        );
    };