标签: std-ranges

std::ranges::begin 和 std::begin 有什么区别?

std::begin和 new 和有什么不一样std::ranges::begin?(同样为endsize等等)

两者似乎工作相同:

#include <iostream>
#include <vector>
#include <array>
#include <ranges>

template<std::ranges::range R>
void printInfo(const R &range)
{
    std::cout << (std::ranges::begin(range) == std::begin(range));
}

template<class T>
struct X
{
    std::vector<T> v;

    auto begin() const { return v.begin(); }
    auto end() const { return v.end(); }
};

int main()
{
    printInfo(std::vector{1, 2, 3, 4});
    printInfo(std::array{1, 2, 3, 4});
    printInfo(X<int>{{1, 2, 3, 4}});

    int oldSchool[]{1, 2, 3, 4};
    printInfo(oldSchool);
}
Run Code Online (Sandbox Code Playgroud)

1111按预期编译和打印。

难道ranges::begin …

c++ range c++20 std-ranges

11
推荐指数
1
解决办法
610
查看次数

您如何使用运算符 | 创建与现有视图交互的自己的视图?

为什么这段代码可以在#if 0块就位的情况下工作,但如果删除它,则会失败并显示一组相当复杂的错误消息?更重要的是,我如何使它与上面非常相似的块得到相同的结果?

#include <ranges>
#include <iterator>
#include <optional>
#include <string_view>
#include <iostream>
#include <algorithm>

template <::std::ranges::view View,
          typename Pred>
requires ::std::ranges::input_range<View> &&
         ::std::ranges::common_range<View> &&
         ::std::is_object_v<Pred> &&
         ::std::indirect_unary_predicate<const Pred, ::std::ranges::iterator_t<View>>
class skip_after_view : public ::std::ranges::view_interface<skip_after_view<View, Pred>>
{
 public:
   skip_after_view() = default;
   skip_after_view(View v, Pred p)
        : subview_(::std::move(v)), pred_(::std::move(p))
   {}
   class iterator;
   friend class iterator;

   auto begin() const {
       return iterator{subview_.begin(), subview_.end(), &pred_};
   }
   auto end() const {
       return iterator{subview_.end(), subview_.end(), &pred_};
   }

 private:
   View subview_ = View();
   Pred pred_; …
Run Code Online (Sandbox Code Playgroud)

c++ g++ libstdc++ c++20 std-ranges

11
推荐指数
1
解决办法
275
查看次数

Range-v3 中是否有一种方法可以将元素添加到范围/视图中?

Range-v3 具有ranges::views::drop和 来ranges::views::drop_last从视图的前面或后面删除元素。

它是否提供类似的功能来将元素添加到视图中?

目前,我发现的最短方法是使用 a或 a到concat范围/容器:iotasingle

#include <assert.h>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/to_container.hpp>

using namespace ranges;
using namespace views;
int main() {
    std::vector<int> v{1,2,3};

    auto wi = concat(iota(0,1),v);
    assert(((wi | to_vector) == std::vector<int>{0,1,2,3}));

    auto ws = concat(single(0), v);
    assert(((ws | to_vector) == std::vector<int>{0,1,2,3}));
}
Run Code Online (Sandbox Code Playgroud)

c++ functional-programming range-v3 c++17 std-ranges

11
推荐指数
0
解决办法
637
查看次数

对于简单的 std::ranges 代码,某些编译器存在错误或编译错误

我有一段使用 C++20 范围库的代码,取自此 SO anwer。该代码被某些编译器(版本)拒绝,并且某些较旧的 GCC 版本返回垃圾。哪个编译器是正确的?

该代码应该打印 a 中第一列的元素std::vector<std::vector>

#include <vector>
#include <string>
#include <ranges>
#include <iostream>

int main()
{
    // returns a range containing only the i-th element of an iterable container
    auto ith_element = [](size_t i) {
        // drop the first i elements in the range and take the first element from the remaining range
        return std::views::drop(i) | std::views::take(1);
    };

    // returns a range over the i-th column
    auto column = [ith_element](size_t i) …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

11
推荐指数
1
解决办法
742
查看次数

为什么“zip_view”不支持“output_range”?

我注意到 C++23zip_view有以下限制:

template<input_range... Views>
  requires (view<Views> && ...) && (sizeof...(Views) > 0)
class zip_view;
Run Code Online (Sandbox Code Playgroud)

这意味着只能zip_view压缩输入范围。

我想知道为什么它排除output_range,因为output_range在我看来支持可能很有用。例如,我可以压缩一堆output_ranges 来同时写入,如下场景:

/* zipped input_range */
auto zip_in = views::zip(views::iota(0, 3),
                         views::iota(3, 6),
                         views::iota(6, 9));

std::vector<int> v1, v2, v3;
auto make_insert_range = [](auto inserter) {
  return ranges::subrange(inserter, std::unreachable_sentinel);
};
/* zipped output_range */
auto zip_out = views::zip(make_insert_range(std::back_inserter(v1)),
                          make_insert_range(std::back_inserter(v2)),
                          make_insert_range(std::back_inserter(v3)));

/* copy */
ranges::copy(zip_in, zip_out.begin());
std::println("v1: {}", v1); // v1: [0, 1, 2]
std::println("v2: {}", …
Run Code Online (Sandbox Code Playgroud)

c++ std-ranges c++23

11
推荐指数
0
解决办法
232
查看次数

C++20 std::ranges::sort 应该不需要支持 std::vector&lt;bool&gt; 吗?

我注意到std::ranges::sort无法排序std::vector<bool>

<source>:6:51: error: no match for call to '(const std::ranges::__sort_fn) (std::vector<bool, std::allocator<bool> >)'
6 |   std::ranges::sort(std::vector{false, true, true});
  |   
Run Code Online (Sandbox Code Playgroud)

这是允许的吗?我们是否需要专门化std::ranges::sortfor std::vector<bool>?是否有关于委员会如何考虑这一点的任何信息?

c++ stdvector c++20 std-ranges

10
推荐指数
1
解决办法
510
查看次数

为什么 std::ranges 算法缺少并行重载(采用执行策略参数)?

C++ 算法库中的许多函数都有重载,采用类型为 的参数ExecutionPolicy,例如std::copy. 但是,我注意到std::ranges命名空间中的相应函数没有这些并行重载。这很不幸,因为这意味着在许多情况下,非范围变体将更有用。

这是什么原因?是否有向std::ranges命名空间添加并行重载的建议?

c++ parallel-processing iterator c++20 std-ranges

10
推荐指数
1
解决办法
290
查看次数

使用范围的向量初始化与 lambda 内联初始化

我想通过转换另一个向量来初始化一个向量。我用两种内联初始化和转换的方式进行了测试std::vector

一种使用 lambda 内联初始化(使用std::transform):

   std::vector<int> foo(100,42);
   const auto fooTimesTwo = [&]{
            std::vector<int> tmp(foo.size());
            std::transform(foo.begin(), foo.end(), tmp.begin(), convert);
            return tmp;
    }();
Run Code Online (Sandbox Code Playgroud)

而另一个 - 使用std::ranges::views::transform

   std::vector<int> foo(100,42);
   auto transform_range = (foo | std::ranges::views::transform(convert));
   std::vector<int> fooTimesTwo {
           transform_range.begin(),
           transform_range.end()
   };
Run Code Online (Sandbox Code Playgroud)

我希望两种向量初始化方式都应该具有相似的性能,但由于某种原因,传统解决方案的基准测试std::transform比第二个方法快得多(快 9.7 倍 -> https://quick-bench.com/q/3PSDRO9UbMNunUpdWGNShF49WlQ) .

我的问题是:

  • 我使用std::ranges::views::transform不当吗?
  • 为什么它的工作速度那么慢?

旁注 - 可以使用 来完成boost::make_transform_iterator,但我无法在 quick-bench 上检查它,因为它们不支持 boost。所以我不确定这种解决方案的效率。

c++ c++20 std-ranges

10
推荐指数
1
解决办法
359
查看次数

clang++-12 找不到库范围

我正在测试 C++ 20 的范围,这是我的main.cpp

#include <ranges>
#include <iostream>

int main()
{
    auto const ints = {0,1,2,3,4,5};
    auto even = [](int i) { return 0 == i % 2; };
    auto square = [](int i) { return i * i; };

    for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
        std::cout << i << ' ';
    }

    std::cout << '\n';
}

Run Code Online (Sandbox Code Playgroud)

编译它clang++-12但找不到“范围”:

$ clang++-12 --version
Ubuntu clang version 12.0.1-++20210525082622+328a6ec95532-1~exp1~20210525063352.95
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin …
Run Code Online (Sandbox Code Playgroud)

c++ clang c++20 std-ranges

10
推荐指数
0
解决办法
5599
查看次数

应该急切地还是懒惰地评估 C++ 约束?

这个问题的主要目的是提请社区注意 libstdc++ 范围不适用于 clang:https ://bugs.llvm.org/show_bug.cgi ? id = 46746

Avi Kivity 建议这是一个 gcc 错误:https ://gcc.gnu.org/bugzilla/show_bug.cgi?id=97120

但随后他也暗示这是一个叮当声错误:https ://bugs.llvm.org/show_bug.cgi ? id = 47509

Rafael Ávila de Espíndola 将问题归结为以下代码,该代码使用 gcc 编译,但不使用 clang:

template <typename _Tp>
concept __member_begin = requires(_Tp __t) {
    {__t.begin()};
};
template <typename _Tp>
concept nothing = requires(_Tp __t) {
    {42};
};
template <typename _Tp>
requires __member_begin<_Tp> void __ranges_begin() {}
template <typename _Derived>
struct view_interface {
    void foo() requires __member_begin<_Derived> {}
    void bar() requires nothing<decltype(__ranges_begin<_Derived>())> {}
};
struct …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++-concepts std-ranges

10
推荐指数
2
解决办法
183
查看次数