3

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?

Jason Rice
  • 1,686
  • 1
  • 12
  • 17
alfC
  • 14,261
  • 4
  • 67
  • 118

1 Answers1

2

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)
    );
};
alfC
  • 14,261
  • 4
  • 67
  • 118
  • 1
    The class name is probably needed by the macro for the pointer to members (e.g. &Person::name). – Jason Rice May 01 '18 at 06:43
  • @JasonRice, which may explain why it shouldn't have the extra template parameters. Actually, it should work with the template parameters in. I don't know. – alfC May 01 '18 at 07:15
  • It would have to be a type which would be an instantiation of a template like `Person`. – Jason Rice May 01 '18 at 22:20