I'm taking my first steps with Boost.Hana, so please bear with me. I have
#include <boost/hana.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
#include <string>
struct A
{
int integer;
std::string string;
};
int main()
{
auto tuple = hana::make_tuple(42, "42");
A a;
hana::for_each(hana::zip(hana::members(a), tuple), [](auto& element) { element[0_c] = element[1_c]; });
}
This is my attempt at assigning each tuple element to its respective (sequential) member of A. This does not work (see live example for complete error). It boils down to
main.cpp:19:54: note: candidate function [with $0 = boost::hana::tuple<int, int>] not viable: expects an l-value for 1st argument
hana::for_each(hana::zip(hana::members(a), input), [](auto& element) { element[0_c] = element[1_c]; });
^
I read in the documentation that Hana algorithms have by-value semantics, but then how would one go about doing this kind of thing? Is constructing an A
from the hana::tuple
the only thing possible?
To modify a Struct
in place, use hana::accessors
which provides a tuple of hana::pair
s each with a key and an accessor function. Also since we don't have reflection yet you need to use one of the macros like BOOST_HANA_ADAPT_STRUCT
to implement A
as a hana::Struct
.
The other answer addresses the lambda taking an rvalue because the zipped tuple is a temporary object.
#include <cassert>
#include <boost/hana.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
#include <string>
struct A
{
int integer;
std::string string;
};
BOOST_HANA_ADAPT_STRUCT(A, integer, string);
int main()
{
auto tuple = hana::make_tuple(42, "42");
A a;
hana::for_each(
hana::zip(hana::accessors<A>(), tuple),
[&a](auto&& element) {
auto accessor_pair = hana::at_c<0>(element);
auto get_member = hana::second(accessor_pair);
get_member(a) = hana::at_c<1>(element);
});
assert(a.integer == 42 && a.string == "42");
}