标签: range-v3

如何编写使用临时容器的范围管道?

我有这个签名的第三方功能:

std::vector<T> f(T t);
Run Code Online (Sandbox Code Playgroud)

我还有一个已命名的潜在无限范围(范围-v3排序).我想创建一个映射到该范围的所有元素的管道,并将所有向量展平为包含其所有元素的单个范围.Tsrcf

本能地,我会写下面的内容.

 auto rng = src | view::transform(f) | view::join;
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为我们无法创建临时容器的视图.

range-v3如何支持这样的范围管道?

c++ range-v3

55
推荐指数
5
解决办法
2275
查看次数

为什么Range-v3在这个例子中比STL慢?

我正在玩Range-v3库以表现出一种荣耀,find_if并且好奇为什么谷歌基准测试一直将我的Range-v3代码排序比我的std::find_if方法更差.g ++和clang都用-O3和表示相同的模式#define NDEBUG.

我想到的具体例子是以下使用STL:

std::vector<int> lengths(large_number, random_number);

auto const to_find = std::accumulate(lengths.begin(), lengths.end(), 0l) / 2;
auto accumulated_length = 0l;
auto found = std::find_if(lengths.begin(), lengths.end(), [&](auto const &val) {
                              accumulated_length += val;
                              return to_find < accumulated_length;
                          });
auto found_index = std::distance(lengths.begin(), found);    
Run Code Online (Sandbox Code Playgroud)

出于此说明的目的,这有点做作,但通常会有一个随机生成器用于向量中的to_find变量和随机值lengths.

使用Range-v3库,我得到以下代码

using namespace ranges;    

std::vector<int> lengths(large_number, random_number);

auto const to_find = accumulate(lengths, 0l) / 2;

auto found_index = distance(lengths | view::partial_sum()
                                    | view::take_while([=](auto const i) …
Run Code Online (Sandbox Code Playgroud)

c++ performance range-v3

29
推荐指数
1
解决办法
2803
查看次数

为什么范围不能用于管道库功能?

乔纳森博卡拉(作者流利C ++)写了一个叫做库的管道

这个“管道”,存储库的主页说,不像范围的使用,即使它看起来一样:它不是基于懒惰的拉动,而是基于急切的推动。但是据说不能使用范围库来执行各种“管道”操作。例如:

  • unzip - 采用压缩输入 - 本质上是一系列 k 元组 - 并产生 k 个单独的、独立的输出。
  • fork - 生成容器/范围的多个(独立)副本。

我不太明白为什么原则上是这样。(当然,除了无法获得结束迭代器/哨兵的范围。)

c++ c++14 range-v3 std-ranges

14
推荐指数
1
解决办法
396
查看次数

根据转换后的值查找最小元素

以下是代码审查中发现的任务.我想根据特殊类型的比较谓词从集合中选择最小值.像这样:

struct Complex { ... };

float calcReduction(Complex elem);

Complex findMinValueWithPredicates(const std::vector<Complex>& values)
{
  auto it = std::min_element(values.begin(), values.end(), 
                             [](const Complex& a, const Complex& b) { 
                               return calcReduction(a) < calcReduction(b); 
                             });

  if (it == values.end()) throw std::runtime_error("");

  return *it;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我找到了基于谓词的最小元素.此谓词计算两个值的减少,float然后比较这些浮点数.工作正常,看起来整洁.

你能看到问题吗?是的,对于一组N元素calcReduction()称为2N时间,而它只足以计算它N- 每个元素一次.

解决此问题的一种方法是编写显式计算:

Complex findMinValueExplicit(const std::vector<Complex>& values)
{
  float minReduction = std::numeric_limits<float>::max();
  Complex minValue;

  for (Complex value : values)
  {
    float reduction = calcReduction(value);
    if (reduction < …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm min range-v3 c++17

13
推荐指数
1
解决办法
1655
查看次数

如何从开始和结束迭代器创建范围?

我有一个带有函数的对象来获取开始和结束迭代器:

const_iterator err_begin() const
const_iterator err_end() const 
Run Code Online (Sandbox Code Playgroud)

因为他们没有被命名beginend,我不能直接把我的对象在范围-V3功能.

有没有一个简单的包装器可以用来使这个对象与range-v3库一起工作?

例如:

auto hasErrors = !empty(something(x.err_begin(), x.err_end())); 
Run Code Online (Sandbox Code Playgroud)

c++ range-v3

13
推荐指数
1
解决办法
1753
查看次数

STL /范围算法计算加权平均值

假设我有一个等级向量,其中等级是

struct Grade{
   const int grade;
   const int ECTS; // weight
};
Run Code Online (Sandbox Code Playgroud)

是否有STL / range-v3算法/算法使我能够做到这一点?

我知道我可以std:: accumulate用一些花哨的类型作为累加器(记住重量的总和)来做到这一点,但是我正在寻找一个更简单的替代方法(如果存在)。

c++ stl weighted-average range-v3

13
推荐指数
2
解决办法
312
查看次数

是否有特征或任何约定来检查范围或`view_facade`是否拥有东西?(例如getlines)

特定

auto empty_line = [](auto& str){ return str.size() == 0; };
Run Code Online (Sandbox Code Playgroud)

对于那个ranges::getlines返回拥有 view_facade其正面迭代器的缓冲区的拥有者的事实.

所以我们有义务在传递算法之前将这种范围变成左值.

auto line_range1 = ranges::getlines(std::cin);
auto iter1 = ranges::find_if_not(line_range1,empty_line);
auto input1 = std::stoi(*iter1);
Run Code Online (Sandbox Code Playgroud)

而且还有一个很酷的保护机制,可以防止所有解除引用迭代器的时间已经被破坏的数据,并使这些尝试编译时错误.

因此,当拥有view_facade作为rvalue传递给算法时,保护将参与解除引用.

这不会编译.

auto iter2 = ranges::find_if_not(ranges::getlines(std::cin),empty_line);
// at this point the `owning` range destroyed, 
// so as the buffer we (should've) hold (before!).

// So this won't compile
// auto input2 = std::stoi(*iter2);
Run Code Online (Sandbox Code Playgroud)

错误为:

<source>:19:29: error: no match for 'operator*' (operand …
Run Code Online (Sandbox Code Playgroud)

c++ range traits range-v3

12
推荐指数
1
解决办法
135
查看次数

容器肯定是概念上的范围吗?

range-v3的文档中:

view::all

返回包含源中所有元素的范围.用于将容器转换为范围.

让我困惑的是:

  1. 在什么情况下view::all使用?
  2. 标准容器(std::vector,std::list等)在概念上不是范围吗?

例如:

auto coll = std::vector{ 1, 2, 2, 3 };  
view::all(coll) | view::unique; // version 1
coll | view::unique; // version 2
Run Code Online (Sandbox Code Playgroud)

有什么区别version 1version 2

c++ standards language-design range-v3 c++-experimental

12
推荐指数
1
解决办法
227
查看次数

view :: join是否需要可复制的内部范围?为什么?

假设我们有

cppcoro::generator<int> gen_impl(int in) {
  const auto upper = in + 10;
  for (; in < upper; ++in)
    co_yield in;
}

cppcoro::generator<cppcoro::generator<int>> gen() {
  for (int n = 1; n < 100; n += 10)
    co_yield gen_impl(n);
}
Run Code Online (Sandbox Code Playgroud)

所以我们可以很好地迭代内部范围

  for (auto&& row : gen() ) {
    for (auto n : row)
      std::cout << n << ' ';
    std::cout << '\n';
  }
Run Code Online (Sandbox Code Playgroud)

注意:范围是for ref是必需的,因为cppcoro::generator不允许复制(删除的副本ctor)

打印

1 2 3 4 5 6 7 8 9 10
11 12 13 14 …
Run Code Online (Sandbox Code Playgroud)

c++ generator coroutine range-v3 c++-coroutine

12
推荐指数
1
解决办法
499
查看次数

Range-v3运算符重载以编写更短的代码

对于我的矩阵类,我想在range-v3视图上进行某种运算符重载(可能使用表达式模板)+ - / * %.例如,如果我想获得两列总和的视图,我想写

col_1 + col_2
Run Code Online (Sandbox Code Playgroud)

代替

rv::zip_with([](auto c1, auto c2) {return c1 + c2;}, col_1, col_2);
Run Code Online (Sandbox Code Playgroud)

可能会使用本文中的一些想法来避免构造太多的临时工.这是我想写的代码:

//simple example
//what I want to write
auto rangeview =    col_1 + col_2;
//what I can write
auto rangeview =    rv::zip_with([](auto c1, auto c2) {
                        return c1 + c2;
                    }, col_1, col_2);


//itermediate
//what I want to write
auto rangeview =    col_1 + col_2 + col_3;
//what I can write
auto rangeview =    rv::zip_with([](auto c1, auto …
Run Code Online (Sandbox Code Playgroud)

c++ range-v3 c++17

12
推荐指数
1
解决办法
261
查看次数