使用不可移动/不可复制的类型创建 hana 元组
Create hana tuple with unmovable / noncopyable types
我正在努力思考伟大的 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;
}
您可以使用几乎与 std::tuple
完全相同的 hana::_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;
}
我正在努力思考伟大的 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;
}
您可以使用几乎与 std::tuple
完全相同的 hana::_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;
}