4

我试图迭代用户定义的结构hana::for_each并注意到它被复制/移动,同时Boost.Fusion允许您就地迭代原始结构。

我没有从in 中找到类似View概念的东西。如何将转换应用于序列而不每次都复制/移动它们?Boost.FusionBoost.Hana

#include <boost/hana.hpp>
#include <iostream>

struct Foo {
    Foo() = default;
    Foo(const Foo&) { std::cout << "copy" << std::endl; }
    Foo(Foo&&) { std::cout << "move" << std::endl; }
};

struct Struct {
    BOOST_HANA_DEFINE_STRUCT(Struct,
        (Foo, foo)
    );
};

int main() {
    Struct s;
    auto m = boost::hana::members(s); // copy constructor invoked
}

更新:我尝试使用hana::transform来申请std::ref成员,但Struct不是 a Functior,因此transform在这种情况下不适用。我能够使用 实现所需的行为hana::accessors,但对我来说它看起来有点 hacky。我希望有一种方法可以创建视图。

hana::for_each(hana::accessors<Struct>(), [&s](const auto& accessor) {
    const auto& member = hana::second(accessor)(s); // No copying
});
4

2 回答 2

4

Jason 说对 Hana 中的观点有实验性支持是正确的。您遇到的问题很常见,Hana 目前并没有以优雅的方式解决它。我希望向 Hana 添加视图可以通过为所有有意义的算法提供按值和按引用语义来解决这个问题。但是以连贯的方式添加它并非易事,因此是该功能的实验状态。

话虽如此,您可以通过使用访问器(如您在问题中所示)或通过迭代与结构成员关联的键来解决您的问题:

#include <boost/hana.hpp>
#include <iostream>
namespace hana = boost::hana;

struct Foo {
    Foo() = default;
    Foo(const Foo&) { std::cout << "copy" << std::endl; }
    Foo(Foo&&) { std::cout << "move" << std::endl; }
};

struct Struct {
    BOOST_HANA_DEFINE_STRUCT(Struct,
        (Foo, foo)
    );
};

int main() {
    Struct s;
    hana::for_each(hana::keys(s), [&s](const auto& key) {
        const auto& member = hana::at_key(s, key); // No copying
    });
}

如果您想将成员本身作为一个序列来操作,但又不想复制它们,您可以创建一个引用序列,如下所示:

#include <boost/hana.hpp>
#include <iostream>
namespace hana = boost::hana;

struct Foo {
    Foo() = default;
    Foo(const Foo&) { std::cout << "copy" << std::endl; }
    Foo(Foo&&) { std::cout << "move" << std::endl; }
};

struct Struct {
    BOOST_HANA_DEFINE_STRUCT(Struct,
        (Foo, foo)
    );
};

int main() {
    Struct s;
    auto members = hana::transform(hana::keys(s), [&s](auto const& key) {
        return std::ref(hana::at_key(s, key));
    });
}

membersstd::reference_wrapper然后将是一个可以随身携带的 s 序列,但是.get()在访问它们时必须使用它们。在 Hana 的未来版本中,hana::members可能会返回键/值对的视图,其中值是对原始成员的引用。但在这成为可能之前,有几个问题必须解决。

希望这可以帮助!

于 2016-05-24T21:44:55.907 回答
3

就视图而言,其中有一些未记录的功能,boost/hana/experimental/view.hpp因此它们肯定会出现在 Boost.Hana 的地平线上。

当前的问题Struct是它Foldable在键值对上。hana::unpack它将把结构中的每个值成对放置,创建一个副本。您使用的解决方案hana::accessors目前是 IMO 的方式。

请注意,目前有一个未解决的问题:https ://github.com/boostorg/hana/issues/175

于 2016-05-23T23:11:39.590 回答