gcc 连接向量范围并不给予范围

jv4diomz  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(79)

我试图做的转换在carpet产品,平整的边缘在年底。我收到的结果whish不是一个范围,这是问题:

#include <ranges>
#include <vector>
#include <iostream>
#include <tuple>
#include <iterator>

int main() {
    auto indicies = std::views::iota(0, 3);

    auto coords = std::views::cartesian_product(indicies, indicies);

    auto edges = coords | std::views::transform([](const auto& coord) {
        using Coord = std::pair<std::size_t, std::size_t>;
        using Edge = std::pair<Coord, Coord>;
        std::vector<Edge> ret;
        const auto& [x, y] = coord;
        auto curr = Coord{x, y};
        if (x + 1 < 3) {
            auto dest = Coord{x + 1, y};
            ret.emplace_back(curr, dest);
        }
        if (y + 1 < 3) {
            auto dest = Coord{x, y + 1};
            ret.emplace_back(curr, dest);
        }
        return ret;
    }) | std::views::join;

    std::cout << edges.cbegin()->first.first << std::endl;

    // static_assert(std::ranges::input_range<const decltype(edges)>);//  <- does not compile with message that ;

    return 0;
}

字符串
g++-13的输出如下(当static_assert未注解时):

<source>: In function 'int main()':
<source>:31:32: error: static assertion failed
   31 |     static_assert(std::ranges::input_range<const decltype(edges)>);//  <- does not compile with message that ;
      |                   ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:31:32: note: constraints not satisfied
In file included from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/string_view:48,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/basic_string.h:47,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/string:54,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/locale_classes.h:40,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/ios_base.h:41,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/streambuf:43,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/streambuf_iterator.h:35,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/iterator:66,
                 from /opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/ranges:43,
                 from <source>:1:
/opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/ranges_base.h:501:13:   required for the satisfaction of 'range<_Tp>' [with _Tp = const std::ranges::join_view<std::ranges::transform_view<std::ranges::cartesian_product_view<std::ranges::iota_view<int, int>, std::ranges::iota_view<int, int> >, main::._anon_155> >]
/opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/ranges_base.h:501:21:   in requirements with '_Tp& __t' [with _Tp = const std::ranges::join_view<std::ranges::transform_view<std::ranges::cartesian_product_view<std::ranges::iota_view<int, int>, std::ranges::iota_view<int, int> >, main::._anon_155> >]
/opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/ranges_base.h:503:22: note: the required expression 'std::ranges::__cust::begin(__t)' is invalid
  503 |         ranges::begin(__t);
      |         ~~~~~~~~~~~~~^~~~~
/opt/compiler-explorer/arm/gcc-13.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/include/c++/13.2.0/bits/ranges_base.h:504:20: note: the required expression 'std::ranges::__cust::end(__t)' is invalid
  504 |         ranges::end(__t);
      |         ~~~~~~~~~~~^~~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
Compiler returned:


我做错了什么?
更新:当我试图将edges传递给一个函数时,问题发生了,该函数将const reference接收到input_range

1l5u6lss

1l5u6lss1#

让我稍微重新检查你的支票,使事情更清楚:

using E = decltype(edges);
static_assert(std::ranges::input_range<E>);       // ok
static_assert(std::ranges::input_range<E const>); // error

字符串
这里的问题是,join视图 * 有时 * 不是const-iterable的-这取决于你加入的范围的类型。特别是,join对输入范围的范围进行操作不会是const-iterable的,因为结果视图必须缓存状态-即使在begin()中-这意味着我们不能将其视为可变的。
这里可能引起混淆的原因是edges.cbegin()实际上可以工作,只是在本例中它实际上并不意味着std::as_const(edges).begin()(在这里不会编译)。相反,cbegin()现在总是存在于范围适配器上,并可靠地返回一个实际常量迭代器。在这里,edges本身是一个引用类型为Edge&的范围,因此edges.cbegin()为您提供了一个引用类型为Edge const&的迭代器。

相关问题