【问题标题】:How to assign to members of a struct object?如何分配给结构对象的成员?
【发布时间】:2019-01-16 22:33:46
【问题描述】:

我正在使用 Boost.Hana 迈出第一步,所以请多多包涵。我有

#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 的相应(顺序)成员。这不起作用(有关完整错误,请参阅live example)。归结为

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 算法有 by-value semantics,但是如何去做这种事情呢?从hana::tuple 构造A 是唯一可能的吗?

【问题讨论】:

  • 这就是Algorithms in Hana always return a new container holding the result. 的建议...鼓励您使用纯函数并创建新对象,而不是对旧对象执行破坏性更新。
  • @user268396 如果我有一个巨大的结构,里面全是复杂的东西,但我想设置一个成员怎么办?这真的不可能吗?与此同时,我发现hana::members(a) = input; 在编译的意义上也“有效”,但同样,lhs 是成员的副本,所以a 永远不会被修改。

标签: c++ c++17 boost-hana


【解决方案1】:

要修改Struct,请使用hana::accessors,它提供了一个hana::pairs 元组,每个元组都有一个键和一个访问器函数。此外,由于我们还没有反射,您需要使用像 BOOST_HANA_ADAPT_STRUCT 这样的宏之一来将 A 实现为 hana::Struct

另一个答案解决了 lambda 采用右值的问题,因为压缩元组是一个临时对象。

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

【讨论】:

  • 好像是这样。我试图将访问器实例绑定到a,但这不是它的工作方式,绑定是在包含的“getter”的调用站点完成的。谢谢!
【解决方案2】:

我对 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> );
                               }
                  );

}

我将您的 lambda 更改为 [&amp;],并将参数更改为 auto&amp;&amp;,然后我使用了 hana::at()。 AFAIK我不认为这是在分配任何东西,但你可能可以使用它并从这里开始,但积极的部分是,在你提供演示代码和相同编译器设置的同一个网站上,这样做了编译没有错误。 Live Demo

【讨论】:

  • 这并没有给我对a 的写访问权限,因为按值语义。我需要像@Jason 建议的访问器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多