标签: std-ranges

如果它是输入范围的最后一个元素,为什么 views::split 忽略分隔符后的空子范围?

对于以下代码

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

int main() 
{
    std::string s = " text ";
    auto sv = std::ranges::views::split(s, ' ');                    
    std::cout << std::ranges::distance(sv.begin(), sv.end());
}
Run Code Online (Sandbox Code Playgroud)

输出为 2。输出范围中不存在最后一个分隔符之后的空子范围。

这似乎不一致,因为N+1如果N输入范围中出现分隔符,我希望输出范围中有子范围。为什么不是这样?

请注意 range-v3 做的完全一样,所以我确定这是故意的,但我想知道为什么。

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

6
推荐指数
0
解决办法
147
查看次数

为什么 const char[] 与 std::ranges::range 的匹配比显式的 const char* 自由重载更好,以及如何修复它?

我想<<为任何人写一个泛型,range最后我得到了这个:

std::ostream& operator << (std::ostream& out, std::ranges::range auto&& range) {
    using namespace std::ranges;

    if (empty(range)) {
        return out << "[]";
    }

    auto current = begin(range);
    out << '[' << *current;

    while(++current != end(range)) {
        out << ',' << *current;
    }

    return out << ']';
}
Run Code Online (Sandbox Code Playgroud)

像这样测试:

int main() {
    std::vector<int> ints = {1, 2, 3, 4};
    std::cout << ints << '\n';
}
Run Code Online (Sandbox Code Playgroud)

它完美运行并输出:

[1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

但是,当测试时:

int main() {
    std::vector<int> empty = {};
    std::cout << empty …
Run Code Online (Sandbox Code Playgroud)

c++ overload-resolution c++-concepts c++20 std-ranges

6
推荐指数
1
解决办法
152
查看次数

与视图一起使用的自定义容器类型的要求

我开始尝试std::ranges并想了解视图是如何真正起作用的。所以我尝试编写自己的容器和迭代器类型,并希望在视图中使用它。

但是似乎缺少一些东西,但编译器只告诉我begin()视图中没有方法,但没有告诉我为什么。

例子:

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

class MyFixedContainer;
class MyIterator
{
    MyFixedContainer* ptr;
    unsigned int offset;
public:
    MyIterator( MyFixedContainer* ptr_, unsigned int offset_ ): ptr{ ptr_},offset{offset_}{}

    bool operator==( MyIterator& other ) const
    {   
        return ( ptr == other.ptr )&& ( offset == other.offset );
    }   

    bool operator!=( MyIterator& other ) const
    {   
        return !(*this == other);
    }   

    MyIterator operator++()
    {   
        offset++;
        return *this;
    }   

    MyIterator operator++(int)
    {   
        MyIterator tmp = *this;
        offset++;
        return …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

6
推荐指数
1
解决办法
314
查看次数

如何使用 range::sort 进行由布尔值控制的升序或降序排序

使用范围允许我减少样板文件,所以这很好,但我找不到按升序或降序排序的方法。以下代码段编译得很好(g++ 10.2.0)并且投影确实简化了代码,不需要 lambda。

  struct Player {
    double score_;
    string name_;
  };

  vector<Player> players{
    {10.0, "Thorin"}, {20.0, "Bombur"}, {15.0, "Bofur"}, {5.0, "Bifur"},
    { 2.0, "Balin"},  {25.0, "Kili"  }, {23.0, "Fili"},  {4.0, "Dwalin"}
  };

  std::ranges::sort(players, std::ranges::less{}, &Player::score_ );

  for(auto const &player : players) {
    cout <<  "Name = " << std::left << setw(10) << player.name_ 
         << " Score = " << player.score_ << endl;
  }
Run Code Online (Sandbox Code Playgroud)

现在我需要一个布尔控制升序或降序排序。

我想写一个这样的简单语句:

 std::ranges::sort(players, sort_ascending ? std::ranges::less() : std::ranges::greater() , &Player::score_);
Run Code Online (Sandbox Code Playgroud)

但是std::ranges::lessstd::ranges::greater没有相同的类型,所以三元运算符将不起作用。

error: operands …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

6
推荐指数
1
解决办法
110
查看次数

Why can views::reverse transform a non-sized_range into a size_range?

In [range.sized#1]:

The sized_­range concept refines range with the requirement that the number of elements in the range can be determined in amortized constant time using ranges?::?size.

template<class T>   
  concept sized_­range =
  range<T> &&
    requires(T& t) { ranges::size(t); };
Run Code Online (Sandbox Code Playgroud)

The standard states that obtaining the size of ranges::sized_range is guaranteed to be in constant time. Consider the following:

auto r1 = std::views::iota(0)
    | std::views::filter([](int x){ return x % 2 == 0; })
    | std::views::take(1'000'000);
Run Code Online (Sandbox Code Playgroud)

r1 is obviously …

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

6
推荐指数
1
解决办法
134
查看次数

C++20 views::join 在生成的嵌套范围上进入无限循环::single_view

我正在使用带有 GCC 实现(v10.2 和 v11)的 C++20 范围。

为了测试行为的std::views::join,我试图生成使用嵌套视图single,然后我平坦它使用join

#include <ranges>
#include <iostream>

int main() {
  auto data = std::views::single(1);
  auto v =
      data
      | std::views::transform([](const auto &s) { return std::views::single(s); })
      | std::views::join
      ;

  for (auto &&x : v) { // Infinite loop + segfault
    std::cout << x << '\n';
  }
}
Run Code Online (Sandbox Code Playgroud)

[在编译器资源管理器中]

我希望找到for 的一个迭代器具有初始值 (1)循环。但是不......它进入了一个无限循环,因为我使用了这个值,所以出现了段错误。

如果我std::views::singlestd::views::iota(a,b)或替换嵌套std::views::empty<int>,则行为完全没问题。

您知道这是否是正确的预期行为(以及为什么)?

编辑

std::ranges::next(v.begin()) == …

c++ c++20 std-ranges

6
推荐指数
0
解决办法
119
查看次数

C++ 范围是否支持视图中的投影?

我知道sort范围内的算法(例如)支持投影,但在我看来,没有办法为视图获得该功能......我对吗?

作为示例,请考虑以下工作代码

#include <algorithm>
#include <ranges>
#include <vector>
#include <iostream>

enum Color {
   Red,
   Green,
   Blue
}; 
struct Cat {
   int age;
   Color color;
};

int main() {
    std::vector<Cat> cats{{.age = 10,.color=Color::Red}, {.age = 20,.color=Color::Blue}, {.age = 30,.color=Color::Green}};
    auto is_red = [](const auto& cat) {return cat.color == Color::Red;};
    for (const auto& cat: cats | std::views::filter(is_red)) {
        std::cout << cat.age << std::endl; 
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法删除 lambda 并执行以下操作:

for (const auto& cat: cats | std::views::filter(&Cat::color, Color::Red) {
Run Code Online (Sandbox Code Playgroud)

注意:我的问题是成员变量投影,但显然在实际代码中也需要成员函数调用。

c++ c++20 std-ranges

6
推荐指数
1
解决办法
354
查看次数

我可以让 `std::ranges::views::elements` 与我的类型范围一起工作吗

考虑Point带有x,yz值的类型。如果我有一系列Point对象,例如std::vector<Point>,我需要添加什么Point才能使其与std::ranges::views::elements范围适配器一起使用?

目的是做类似的事情

std::vector<Point> v{...};
for (auto x : v | std::ranges::views::elements<0>) {
    // do something with all `x` values
}
Run Code Online (Sandbox Code Playgroud)

文档提到std::ranges::views::elements适用于“类似元组”的值。我假设它的工作方式应该类似于我们如何使我们的类型与结构化绑定一起工作,但我似乎遗漏了一些东西

我已尝试使用以下代码

class Point {
    double x=0;
    double y=0;
    double z=0;
public:
    Point(double x, double y, double z) : x(x), y(y), z(z) {}

    template <std::size_t N>
    double get() const {
        if constexpr(N == 0)
            return x;
        else if …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

6
推荐指数
1
解决办法
72
查看次数

std::lexicographyal_compare_third_way 用于范围

为什么有std::lexicographical_compare_three_way,却没有std::ranges::lexicographical_compare_three_way

中有参数 Comp std::ranges::lexicographical_compare,但它相当无用,因为bool当需要比较类别类型之一时,函数返回 。

以下是 cppref 的一些链接
https://en.cppreference.com/w/cpp/algorithm/lexicographyal_compare_ Three_way
https://en.cppreference.com/w/cpp/algorithm/ranges/lexicographyal_compare

c++ c++20 std-ranges

5
推荐指数
1
解决办法
368
查看次数

有没有一种有效的方法可以在转换后使用views::filter?(范围适配器)

奇怪行为的常见示例views::filter

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

int main ()
{
    using namespace std;

    auto ml = [](char c) // ml = make lambda (always accepts / transforms to 1)
    {
        return [c](int) {cout << c; return 1;};
    };

    vector<int> vec = {1};
    
    auto view = vec
        | views::transform  (ml('T'))
        | views::filter     (ml('F'));
    
    // use view somehow:
    return *view.begin();
}
Run Code Online (Sandbox Code Playgroud)

哪个输出TFT(注意额外的T)。演示


我们必须知道:

auto view = vec
    | views::transform  (ml('A'))
    | views::filter     (ml('B'));
Run Code Online (Sandbox Code Playgroud)

...只是语法糖: …

c++ gcc g++ c++20 std-ranges

5
推荐指数
1
解决办法
4418
查看次数

标签 统计

c++ ×10

c++20 ×10

std-ranges ×10

range-v3 ×2

c++-concepts ×1

g++ ×1

gcc ×1

overload-resolution ×1