我怎样才能使 std::vector class 成为一个序列,以便它可以传递给 boost::hana::group?

How can I make the std::vector class a Sequence so that it can be passed to boost::hana::group?

我希望编译并运行以下代码:

#include <boost/hana/group.hpp>
#include <functional>
#include <vector>
int main() {
    std::vector<int> x = {1,1,3,4};
    auto groups = boost::hana::group(x, std::equal_to<>{});
}

试图编译错误如下:

$ g++ -std=c++2a deleteme.cpp && ./a.out
In file included from deleteme.cpp:1:
/usr/include/boost/hana/group.hpp: In instantiation of ‘constexpr auto boost::hana::group_t::operator()(Xs&&, Predicate&&) const [with Xs = std::vector<int>&; Predicate = std::equal_to<void>]’:
deleteme.cpp:6:44:   required from here
/usr/include/boost/hana/group.hpp:55:42: error: static assertion failed: hana::group(xs, predicate) requires 'xs' to be a Sequence
   55 |         static_assert(hana::Sequence<S>::value,
      |                                          ^~~~~
/usr/include/boost/hana/group.hpp:59:28: error: use of deleted function ‘static constexpr auto boost::hana::deleted_implementation::apply(T&& ...) [with T = {std::vector<int, std::allocator<int> >&, std::equal_to<void>}]’
   59 |         return Group::apply(static_cast<Xs&&>(xs),
      |                ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
   60 |                             static_cast<Predicate&&>(pred));
      |                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/hana/core/dispatch.hpp:14,
                 from /usr/include/boost/hana/drop_front.hpp:18,
                 from /usr/include/boost/hana/concept/iterable.hpp:20,
                 from /usr/include/boost/hana/at.hpp:16,
                 from /usr/include/boost/hana/group.hpp:15,
                 from deleteme.cpp:1:
/usr/include/boost/hana/detail/dispatch_if.hpp:21:31: note: declared here
   21 |         static constexpr auto apply(T&& ...) = delete;
      |                               ^~~~~

因此我明白原因是 std::vector 不满足 Sequence 的概念,但我如何强制执行它呢?

我一直在查看 /usr/include/boost/hana/fwd/concept/sequence.hpp/usr/include/boost/hana/concept/sequence.hpp,但目前这些文件中的模板元元编程对我来说仍然有点重,无法在没有任何帮助的情况下理解它.

This is an excerpt from Hana's documentation,我认为这解决了问题。关键是我不知道如何将处方转化为代码:

For this reason, it is necessary to specialize the Sequence metafunction in Hana's namespace to tell Hana that a type is indeed a Sequence. Explicitly specializing the Sequence metafunction can be seen like a seal saying "this data type satisfies the additional laws of a Sequence", since those can't be checked by Hana automatically.

虽然可以使用涉及仅在 run-time、Boost.Hana 中知道的不同维度的类型来实现 Boost.Hana 中的一些概念。序列和一些概念是其“最小完整定义”的一部分要求在 compile-time.

处知道长度和元素
  • Foldable 要求在 compile-time.
  • 处知道长度
  • Iterable 要求每个元素都可以在 compile-time.
  • 处访问
  • Sequence 需要 FoldableIterable.

需要 Sequencegroup 函数和 std::vector 的 run-time 长度使得这不可能。

Boost.Hana 手册中的 Computational Quadrants 部分详细说明了需要 compile-time 与 run-time 信息的算法。

Group 概念可能可行,但我认为这不是问题的一部分。)

关于为标准类型专门化第三方模板的评论,这是可能的,但被认为是错误的形式。解决方案是制作某种包装类型或提供您自己的概念。

编辑:

一条评论建议将 std::array 实现为 Sequence,因为它的长度在 compile-time 处已知。虽然我在 Sequence 的“法则”中找不到禁止同类类型列表的灵丹妙药,但我可以说 Sequence 的前提是使用异构类型的数据结构。元素可能包含 run-time 数据,但算法中的所有谓词都完全依赖于“compile-time”信息,因此像 group 这样的函数对于 std::array 是完全无用的。 (这在前面提到的link中有解释)