创建具有不可移动/不可复制类型的hana元组

Create hana tuple with unmovable / noncopyable types

本文关键字:类型 hana 元组 可复制 可移动 创建      更新时间:2023-10-16

我正在努力理解boost::hana,并试图弄清楚如何翻译一些老式的元组代码。

也许这有点特殊,但我有既不可复制也不可移动的类型,并希望将它们打包在一个容器中。思考政策设计…

我想我只是不知道如何在价值世界中创建一个hana元组。我尝试的方式不起作用,因为make<Tuple>(CompT{}...)需要可复制或至少可移动的类型。

所以很可能这不是正确的方法。或者这是hana的局限性?

谢谢!

struct NonMoveable
{
    NonMoveable() = default;
    NonMoveable(const NonMoveable& other) = delete;
    int val;
};
struct Simple { int val; };
template <typename ...CompT>
struct OldSchoolContainer
{
    template <int I>
    auto& getComponent()
    {
        return std::get<I>(components);
    }
    std::tuple<CompT...> components;
};
template <typename ...CompT>
struct HanaContainer
{
    using Args_t = decltype(make<Tuple>(CompT{}...));
    template <int I>
    auto& getComponent()
    {
        return components[int_<I>];
    }
    Args_t components;
};
int main()
{
    OldSchoolContainer<Simple> simpleOsc;
    static_assert(std::is_same<Simple&, decltype(simpleOsc.getComponent<0>())>::value, "");
    HanaContainer<Simple> simpleHanaC;
    static_assert(std::is_same<Simple&, decltype(simpleHanaC.getComponent<0>())>::value, "");

    OldSchoolContainer<NonMoveable> nonmoveableOsc;
    static_assert(std::is_same<NonMoveable&, decltype(nonmoveableOsc.getComponent<0>())>::value, "");
    // !!! this does not compile because hana's tuple closure needs to either move or copy
    HanaContainer<NonMoveable> nonmoveableHanaC;
    static_assert(std::is_same<NonMoveable&, decltype(nonmoveableHanaC.getComponent<0>())>::value, "");
    return 0;
}

您可以使用hana::_tuple<...>类型几乎与std::tuple完全相同。因此,下面的工作:

#include <boost/hana/integral_constant.hpp>
#include <boost/hana/tuple.hpp>
#include <tuple>
#include <type_traits>
namespace hana = boost::hana;

struct NonMoveable
{
    NonMoveable() = default;
    NonMoveable(const NonMoveable& other) = delete;
    int val;
};
struct Simple { int val; };
template <typename ...CompT>
struct HanaContainer
{
    template <int I>
    auto& getComponent()
    {
        return components[hana::int_<I>];
    }
    hana::_tuple<CompT...> components;
};
int main()
{
    HanaContainer<Simple> simpleHanaC;
    static_assert(std::is_same<Simple&, decltype(simpleHanaC.getComponent<0>())>::value, "");
    HanaContainer<NonMoveable> nonmoveableHanaC;
    static_assert(std::is_same<NonMoveable&, decltype(nonmoveableHanaC.getComponent<0>())>::value, "");
    return 0;
}