Как назначить членам объекта структуры? - PullRequest
0 голосов
/ 17 января 2019

Я делаю свои первые шаги с Boost.Хана, поэтому, пожалуйста, потерпите меня. У меня

#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]; });
}

Это моя попытка присвоить каждому элементу кортежа соответствующий (последовательный) член A. Это не работает (см. живой пример для полной ошибки). Сводится к

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]; });
                                                    ^

Я прочитал в документации, что алгоритмы Hana имеют семантику по значению , но тогда как можно поступить таким образом? Возможно ли создание A из hana::tuple единственно возможного?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Чтобы изменить Struct на месте, используйте hana::accessors, который предоставляет набор из hana::pair с каждым с ключом и функцией доступа. Кроме того, поскольку у нас пока нет отражения, вам нужно использовать один из макросов, таких как BOOST_HANA_ADAPT_STRUCT, чтобы реализовать A как hana::Struct.

Другой ответ обращается к лямбде, принимающему r-значение, потому что сжатый кортеж является временным объектом.

#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");
}
0 голосов
/ 17 января 2019

Я не очень знаком ни с Boost, ни с Hana; но я пошел на их сайт и прочитал немного их документации по некоторым их объектам, функциям и т. д. Я не знаю, поможет ли это вам, но мне удалось немного изменить ваш код, и я получил это для компиляции:

int main() {
    A a;
    auto tuple = hana::make_basic_tuple( 42, "42" );

    hana::for_each( hana::zip( hana::members(a), tuple), 
                               [&](auto&& element) {
                                   hana::at( tuple, hana::size_c<0> );
                                   hana::at( tuple, hana::size_c<1> );
                               }
                  );

}

Я изменил вашу лямбду на [&] и изменил параметр на auto&&, и я использовал hana::at(). AFAIK Я не думаю, что это что-то назначает в данный момент, но вы могли бы использовать это и перейти отсюда, но положительным моментом является то, что на том же веб-сайте вы предоставили свой демо-код и с теми же настройками компилятора, это сделало скомпилировать без ошибок. Live Demo

...