Создайте кортеж hana с неподвижными / не копируемыми типами

Я пытаюсь обернуть голову вокруг великолепного boost :: hana и попытаться выяснить, как перевести какой-нибудь код старой школы.

Может быть, это немного особенное, но у меня есть типы, которые нельзя ни копировать, ни перемещать, и я хочу упаковать их в контейнер. Подумайте, дизайн политики …

Я думаю, я просто не понимаю, как создать кортеж хана в мире ценностей. То, как я пытаюсь, не работает, потому что make<Tuple>(CompT{}...) нужны типы, которые можно копировать или, по крайней мере, перемещать.

Так что, скорее всего, это просто не способ сделать это. Или это ограничение ханы?

Спасибо!

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;
}

1

Решение

Вы можете использовать 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;
}
2

Другие решения