标签: range-v3

如何为random_shuffle编写range-v3动作?

使用range-v3库(@EricNiebler),使编写算法代码更紧凑,例如,这里是如何生成一堆随机数:

#include <range/v3/all.hpp>
#include <iostream>
#include <vector>

int main() 
{
    using namespace ranges;

    auto const N = 10;
    std::vector<int> v; 
    v.reserve(N);

    v |= action::push_back(view::iota(0, N)); 
    random_shuffle(v);
    copy(v, ostream_iterator<>(std::cout, ","));
}
Run Code Online (Sandbox Code Playgroud)

实例.

不过,我更愿意用一个假想延长了管道action::random_shuffle()这样

v |= action::push_back(view::iota(0, N)) | action::random_shuffle();
Run Code Online (Sandbox Code Playgroud)

这是我尝试编写这样的动作(不幸的是,编写新的range-v3代码比使用库更加冗长)

#include <functional> // bind, placeholders::_1

namespace ranges
{
    inline namespace v3
    {
        /// \addtogroup group-actions
        /// @{
        namespace action
        {
            struct random_shuffle_fn
            {
            private:
                friend action_access;

                static auto bind(random_shuffle_fn random_shuffle)
                RANGES_DECLTYPE_AUTO_RETURN
                (
                    std::bind(random_shuffle, std::placeholders::_1)
                )

                template<typename Gen> …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm c++14 range-v3

7
推荐指数
1
解决办法
544
查看次数

使用gsl :: span和range-v3

我尝试了一个小例子来熟悉GSL和range-v3库,我想知道它们如何协同工作.我有这个玩具的例子

#include <iostream>
#include <range/v3/all.hpp>

using namespace std;
using namespace ranges;

void example_vector(vector<int> const& v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

int main()
{
   auto seq = vector<int> { 2,2,2,0,0,2,1,2 };
   example_vector(seq);
}
Run Code Online (Sandbox Code Playgroud)

哪个有效.但是,如果我尝试使用gsl::span<int>范围,则会导致错误消息.编译器告诉我span没有满足视图概念.

#include <gsl.h>

// ...

void example_span(gsl::span<const int> v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)

编译器消息:

note: candidate template ignored: disabled by 'enable_if'
      [with Rng …
Run Code Online (Sandbox Code Playgroud)

c++ range-v3 guideline-support-library

7
推荐指数
1
解决办法
1055
查看次数

为什么范围v3算法不能管道化?

似乎范围v3中的算法不可链接,即:

const auto ints = std::vector<int>{1,2,1,3,1,4,1,5,1,6};
const auto num_ones = ints | ranges::count(1);
Run Code Online (Sandbox Code Playgroud)

...必须写成功能风格:

const auto num_ones = ranges::count(ints, 1);
Run Code Online (Sandbox Code Playgroud)

这是一种设计选择,只有返回新范围/容器的算法/操作才是可管理的吗?

c++ stl range-v3

7
推荐指数
1
解决办法
399
查看次数

将范围分割为重叠范围的范围

我尝试使用Ranges-V3库将一个值容器切割成一系列范围,使相邻范围共享边界元素.

考虑以下:

using namespace ranges;

std::vector<int> v = { 1, 2, 3, 0, 4, 0, 5, 0, 6, 7, 8, 0, 0, 9 };
auto myRanges = v | /* something like adjacent split */
for_each( myRanges, []( auto&& range ){ std::cout << range << std::endl;} );
Run Code Online (Sandbox Code Playgroud)

我想根据区域是否满足两个标准,将范围划分为重叠的子范围:

  1. 元素的值是否为零
  2. 或者与一个或多个值为零的元素相邻

期望的输出:

[1,2,3]
[3,0,4,0,5,0,6]
[6,7,8]
[8,0,0,9]
Run Code Online (Sandbox Code Playgroud)

我的尝试:

auto degenerate =
  []( auto&& arg ){
    return distance( arg ) < 2;  
  };

auto myRanges = v | view::split(0) | view::remove_if( degenerate ); …
Run Code Online (Sandbox Code Playgroud)

c++ c++14 range-v3

7
推荐指数
1
解决办法
612
查看次数

向量矢量范围的范围

假设我有一系列名为rng的T.我可以

auto groups = ranges::view::group_by(rng, bin_op);
Run Code Online (Sandbox Code Playgroud)

群体现在是T的范围.

我也可以这样做

auto groups = ranges::view::group_by(rng, bin_op) | ranges::to_vector;
Run Code Online (Sandbox Code Playgroud)

得到T的范围向量.不过这个

auto groups = ranges::view::group_by(rng, bin_op)
            | ranges::to_vector
            | ranges::action::transform([] (auto r) { return r | ranges::to_vector; };
Run Code Online (Sandbox Code Playgroud)

以及

auto groups = ranges::view::group_by(rng, bin_op)
            | ranges::to_vector
            | ranges::action::transform([] (auto r) { return std::vector<T>{} | ranges::action::push_back; };
Run Code Online (Sandbox Code Playgroud)

因为看起来range :: action :: transform()在这种情况下返回void并且"传递给action :: transform的函数的结果类型必须可写回源范围",因此不起作用.

那么如何将范围范围转换为矢量矢量?

注意:对不好的标签很抱歉,但我找不到范围/ range-ts/ranges-v3标签,我不允许创建一个标签,也不能在标题中使用它.

c++ range-v3

7
推荐指数
2
解决办法
620
查看次数

如何将std :: string拆分为std :: string_views的范围(v3)?

我需要std::string在所有空间拆分.但是,结果范围应该将其元素转换为std::string_views.我正在努力研究该系列的"元素类型".我想,类型就像是一个类似的东西c_str.如何将"分裂"部分转换为string_views?

#include <string>
#include <string_view>
#include "range/v3/all.hpp"

int main()
{
    std::string s = "this should be split into string_views";

    auto view = s 
            | ranges::view::split(' ') 
            | ranges::view::transform(std::string_view);
}
Run Code Online (Sandbox Code Playgroud)

c++ string range-v3 string-view

7
推荐指数
1
解决办法
963
查看次数

迭代容器或范围 - constness的问题

我正在尝试编写一个模板函数,它将汇总某些集合的所有元素 - 指定为普通的stl容器,或指定为range-v3的范围.(实际的功能,如下所示更通用)我认为这样可行:

template <typename Range, typename Ret, typename Func>
std::pair<Ret, int> sum(const Range& range, Ret zero, Func extract) {
  using It = decltype(range.begin());
  Ret sum = zero;
  int numElements = 0;
  for (It it = range.begin(); it != range.end(); ++it) {
    sum += extract(*it);
    ++numElements;
  }
  return { sum, numElements };
}
Run Code Online (Sandbox Code Playgroud)

这确实适用于STL元素,但不适用于范围.这给了我一个很长的错误:

<this file, at line 'using It'> error C2662: 'ranges::v3::basic_iterator<ranges::v3::adaptor_cursor<ranges::v3::basic_iterator<ranges::v3::adaptor_cursor<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>,ranges::v3::iter_transform_view<Rng,ranges::v3::indirected<Fun>>::adaptor<false>>>,ranges::v3::remove_if_view<ranges::v3::transform_view<Rng,Fun>,ranges::v3::logical_negate_<EnemyGroup::stepUpdate::<lambda_c582fb1297dce111c4572cef649d86b9>>>::adaptor>> ranges::v3::view_facade<Derived,ranges::v3::finite>::begin<Derived,false,0x0>(void)': cannot convert 'this' pointer from 'const Range' to 'ranges::v3::view_facade<Derived,ranges::v3::finite> &'
note: Conversion loses qualifiers
Run Code Online (Sandbox Code Playgroud)

最初,我认为这是范围-v3的vs2015分支的一些缺陷.没有多想,我只是快速解决了:

template …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ range-v3

7
推荐指数
1
解决办法
137
查看次数

如何在两个 C++20 范围上实现延迟计算的函数?

zip_withEric Niebler 提供了一个函数。

但是,既然 C++20 支持范围,我想构建类似的东西。

这个问题filter,并transform为他们迭代的范围?

我该怎么做呢?我已经坚持了一段时间,并且不愿意使用表达式模板。

例如,假设我有两个向量 M1{1,2,3} 和 M2{4,5,6}。

我想使用范围库来重载运算符以返回包含这两个矩阵相加的视图 - M1+M2 := {5,7,9}

使用 range-v3,我可以执行 auto sum = zip_with(std::plus,M1,M2);

上面的表达式是惰性求值的。如何使用 C++20 范围重新创建此表达式?

c++ lazy-evaluation range-v3 c++20

7
推荐指数
1
解决办法
355
查看次数

C++20 中的 iterator_category 和 iterator_concept 有什么区别?

C++20带来了更强大的迭代器系统,其中之一就是iterator_conceptiterator_category.

我发现C++20 中很多迭代器的iterator_conceptiterator_category是不一致的。以最著名iota_view为例

using R = decltype(views::iota(0));
static_assert(random_access_range<R>);

using I = ranges::iterator_t<R>;
static_assert(same_as<typename I::iterator_category, input_iterator_tag>);
static_assert(same_as<typename I::iterator_concept,  random_access_iterator_tag>);
Run Code Online (Sandbox Code Playgroud)

虽然是Rmodels random_access_range,但iterator_category它的迭代器的the只是一个input_iterator_tag,与iterator_concept.

为什么C++20引入iterator_concept?它的目的是什么?如果我实现我自己的迭代器,我该如何界定iterator_conceptiterator_category正确?是否iterator_category仍然在C ++ 20的意思?

c++ iterator range-v3 c++20 std-ranges

7
推荐指数
1
解决办法
201
查看次数

使用 Ranges-V3 移除标记为移除的元素

我有两个向量:

struct MyData{
     double value; 
};
std::vector<int> remove_flags = {0, 1, 0, 0, 0, 0, 1, 0};
std::vector<MyData> data =      {{},{},{},{},{},{},{},{}}; 
Run Code Online (Sandbox Code Playgroud)

remove_flags向量包含一个大小与 完全相同的标志数组data,每个标志要么是 0,要么是 1,其中 1 表示应删除数据。

我想用来remove_flagsdata原地删除元素,即执行擦除删除习语,但根据remove_flags. 最终结果应该是data删除了元素,并希望删除remove_flags了那些相同的元素。

手动执行此操作很烦人,我想为此使用 Range-v3。我目前正在使用 C++17。

在查看文档后,我认为我没有找到解决方案,我能想到的最接近的事情是:

auto result = ranges::views::zip(remove_flags, data) | ranges::actions::remove_if([](std::pair<const int&, const MyData&> pair){
    return pair.first != 0;
});

remove_flags.erase(result.first, remove_flags.end());
data.erase(result.second, data.end());
Run Code Online (Sandbox Code Playgroud)

但是操作无法对视图 zip 进行操作,因此无法编译。如果我切换ranges::actions::remove_ifranges::views::remove_if一个奇怪的视图对象被返回,大概是一个没有实际std::remove对两个向量执行等效操作的对象。

可以使用,contaner_to …

c++ erase-remove-idiom range-v3 c++17

7
推荐指数
1
解决办法
195
查看次数