gpt4 book ai didi

c++ - Boost Hana 实现自定义序列

转载 作者:行者123 更新时间:2023-12-01 14:20:17 28 4
gpt4 key购买 nike

我面临的情况是,我通常会通过继承 boost::hana::tuple 来创建自定义类。例如,通过使用以下代码,

template<typename ... args>
struct my_nonworking_custom_tuple_t : public boost::hana::tuple<args ...> //not working!!!
{
using base = boost::hana::tuple<args ...>;
//... all other stuff

auto my_getter() const { return base::operator[](1_c); }
};

但是,这不起作用,因为 boost::hana::tuple 是作为 final 实现的。

因此看来我不得不使用组合,

template<typename ... args>
struct my_custom_tuple_t
{
//... all other stuff
boost::hana::tuple<args ...> tup;
auto my_getter() const { return tup[1_c]; }
};

但是,一旦我这样做,生成的类就不再对 Hana 概念“序列”建模,因此我无法应用所有方便的 Hana 方法。

我需要做什么才能将 my_custom_tuple_t 转换为 Hana 序列?

最佳答案

通常您不需要这样做,但这里有一个指南,用于实现您自己的 Sequence 以及满足 Boost.Hana 中其他概念的要求。 (后者应该对不提供自己的元组实现的最终用户有用。)

hana::Sequence 文档中的最小完整定义 (MCD) 开始

您会看到要实现Sequence,您的数据类型必须实现make 函数并满足Iterable 的要求。和 Foldable .

因此,您必须为其提供实现的 Hana 函数的完整列表如下:

  • drop_front
  • is_empty
  • 制作
  • 解压

此外,请注意 Boost.Hana 有两种元组类型 tuplebasic_tuplebasic_tuple 更轻量,因此您应该将其用于存储。

要使用 Boost.Hana 的标签调度,您可以实现 hana::tag_of 或简单地提供一个 hana_tag 类型别名作为您的类的成员。

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

namespace mine {
struct my_custom_tuple_tag { };

template<typename ... args>
struct my_custom_tuple_t {
using hana_tag = my_custom_tuple_tag;
//... all other stuff
boost::hana::basic_tuple<args ...> tup;

auto my_getter() const {
return boost::hana::at_c<1>(tup);
}
};
}

namespace boost::hana {
// Iterable

template <>
struct at_impl<mine::my_custom_tuple_tag> {
template <typename Xs, typename N>
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
return at_impl<basic_tuple_tag>(std::forward<Xs>(xs).tup, N{});
}
};

template <>
struct drop_front_impl<mine::my_custom_tuple_tag> {
template <typename Xs, typename N>
static constexpr auto apply(Xs&& xs, N const&) {
return drop_front_impl<basic_tuple_tag>(std::forward<Xs>(xs).tup);
}
};

template <>
struct is_empty_impl<mine::my_custom_tuple_tag> {
template <typename Xs>
static constexpr auto apply(Xs const& xs) {
return is_empty_impl<basic_tuple_tag>(xs).tup;
}
};

// Foldable

template <>
struct unpack_impl<mine::my_custom_tuple_tag> {
template <typename Xs, typename F>
static constexpr auto apply(Xs&& xs, F&& f) {
return unpack_impl<basic_tuple_tag>(std::forward<Xs>(xs).tup,
std::forward<F>(f));
}
};

// Sequence

template <>
struct make_impl<mine::my_custom_tuple_tag> {
template <typename ...Args>
static constexpr auto apply(Args&& ...args) {
return make_impl<basic_tuple_tag>(std::forward<Args>(args)...);
}
};

template <>
struct Sequence<mine::my_custom_tuple_tag> : std::true_type { };
}

值得注意的是,用于检查 Sequence 的模板只是一个可选的模板特化。我确信这只是节省编译时计算的捷径,因为其他概念依赖于检查其所需函数的非默认实现。

https://godbolt.org/z/iaYBFq

关于c++ - Boost Hana 实现自定义序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61844206/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com