【问题标题】:How can I make the std::vector class a Sequence so that it can be passed to boost::hana::group?如何使 std::vector 类成为一个序列,以便可以将其传递给 boost::hana::group?
【发布时间】:2020-12-04 13:54:12
【问题描述】:

我希望以下代码能够编译和工作:

#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,我认为它解决了这个问题。关键是我不知道如何将这些处方翻译成代码:

因此,有必要专门化 Hana 命名空间中的 Sequence 元函数告诉 Hana 一个类型 确实是一个序列。明确专业化 序列元函数可以看作是一个印章,上面写着“这个数据 类型满足 Sequence" 的附加法则,因为那些不能 由 Hana 自动检查。

【问题讨论】:

  • 您不能强制使用您未编写的标准库类型来匹配您未编写的概念??
  • 我在质疑你的问题,因为它在逻辑上是不可能的。
  • 除非您提供自己的编译器库,否则实际上是不可能的
  • @BaileyKocin 然后写一个答案,用比你不能不可能更具体的东西来证明你的陈述。

标签: c++ functional-programming c++14 template-meta-programming boost-hana


【解决方案1】:

虽然可以使用涉及仅在运行时知道的不同维度的类型来实现 Boost.Hana 中的一些概念,但 Boost.Hana.Sequence 和一些属于其“最小完整定义”的概念" 要求在编译时知道长度和元素。

  • Foldable 要求在编译时知道长度。
  • Iterable 要求每个元素在编译时都可以访问。
  • Sequence 需要 FoldableIterable

需要Sequencegroup 函数和std::vector 的运行时长度使这成为不可能。

Boost.Hana 手册中的Computational Quadrants 部分详细介绍了需要编译时与运行时信息的算法。

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

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

编辑:

评论建议将std::array 实现为Sequence 的示例,因为它的长度在编译时是已知的。虽然我在Sequence 的“法律”中找不到禁止同质类型列表的灵丹妙药,但我可以说Sequence 的前提是使用异构类型的数据结构。元素可能包含运行时数据,但算法中的所有谓词都完全依赖于“编译时”信息,因此像group 这样的函数对于std::array 完全没用。 (这在前面的链接中有解释)

【讨论】:

  • 关于专业化 [...],摘自 Boost.Hana 的文档,在我的问题末尾似乎暗示专业化是要走的路,所以你为什么说 格式不好?但是,如果问题是 std::vector 具有运行时长度,您能否举一个 std::array 的示例,它的长度在编译时已知?
  • 专业化 Sequence 很好,但是如果你将它专门化为标准类型,你可能会破坏与可能选择专门化它的 Boost.Hana 版本的兼容性。
  • 实现Sequence的一个例子:stackoverflow.com/a/61879631/800347
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-10
  • 2021-12-28
  • 2012-11-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多