标签: std-ranges

std::views 命名空间在 Xcode 的 C++ 中不可用吗?

我有 Xcode 14 beta,我尝试从 cppreference.com编译这个连接示例。

#include <iostream>
#include <ranges>
#include <string_view>
#include <vector>
 
int main()
{
    using namespace std::literals;
    const auto bits = { "https:"sv, "//"sv, "cppreference"sv, "."sv, "com"sv };
    for (char const c : bits | std::views::join) std::cout << c; // Error 1
    std::cout << '\n';
 
    const std::vector<std::vector<int>> v{ {1,2}, {3,4,5}, {6}, {7,8,9} };
    auto jv = std::ranges::join_view(v);  // Error 2
    for (int const e : jv) std::cout << e << ' ';
    std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我收到错误: …

c++ xcode c++20 std-ranges

4
推荐指数
1
解决办法
1802
查看次数

为什么 std::ranges::contains 不尝试使用成员 contains 就像 std::ranges::begin 尝试使用成员开始一样?或者确实如此?

std::begin.begin如果参数有成员函数,则可以调用该成员函数。似乎也std::ranges::begin做同样的事情。

但是,在 的 页面上,std::ranges::contains我没有看到提及member一词,也没有看到.contains. 这是为什么?

我的意思是,如果我要写,std::ranges::contains(someRange, someVal)我真的希望它会导致对 member 的调用contains,如果someRange碰巧是 astd::mapsomeVala key 。

我还查看了ranges::containsRange-v3,在我看来,它也只是在范围内进行线性搜索,对支持 member 的参数没有特殊处理contains

c++ performance c++20 std-ranges c++23

4
推荐指数
1
解决办法
634
查看次数

views::iota 与 Ranges::iota_view - “等价表达式”那么为什么两者都存在呢?

#include <iostream>
#include <ranges>

int main()
{
    for (int num: std::ranges::views::iota(0,5)) {
        std::cout << num << 'n';
    }
    
    for (int i : std::ranges::iota_view{55, 65}) {
        std::cout << i << '\n';
    }
}
Run Code Online (Sandbox Code Playgroud)

CPP 参考

  1. views::iota(e)对于任何合适的子表达式和 ,和views::iota(e, f)分别与和表达式等价。iota_view(e)iota_view(e, f)ef

是否有理由使用其中一种与另一种?

如果不是,既然它们都是在 C++20 中引入的,为什么还要存在呢?

c++ iota c++20 std-ranges

4
推荐指数
1
解决办法
455
查看次数

如何在 C++23 中迭代 2 个容器的“枚举 zip”?

如何在 C++23 中迭代 2 个容器的“枚举 zip”?
在Python中,我会写这样的东西:

A = [10, 20, 30]
B = [40, 50, 60]
for (i, (a, b)) in enumerate(zip(A, B)):
  print(i, a, b)
Run Code Online (Sandbox Code Playgroud)

它依次输出和中的索引i和相应元素。AB

在 C++23 中enumeratezip存在等效项 ( <ranges>),但我不知道如何正确组合它们。

  using namespace std;
  
  auto A = vector {10, 20, 30};
  auto B = vector {40, 50, 60};
  
  // zip
  for (auto [a, b]: views::zip(A, B))
    cout << a << " " << b << "\n";
  
  // enumerate
  for …
Run Code Online (Sandbox Code Playgroud)

c++ std-ranges c++23

4
推荐指数
1
解决办法
160
查看次数

分块列表后未找到子范围的 C++ 返回方法

我遇到了这种奇怪的行为,如果您创建一个列表的分块视图(由 2 个元素组成),然后尝试在范围 for 循环中打印正面和背面,则前面的方法将起作用,但后面的方法将不起作用t。它将产生一个编译器错误,指出实例化 .back() 方法需要双向迭代器。我错过了什么吗?

重现错误的代码

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

int main() {
  std::list<int> nums_list = {0, 1, 2, 3, 4, 5};

  auto rng = nums_list | std::views::chunk(2);
  for (auto pair : rng) {
    std::cout << pair.front(); // Front will work normally
    std::cout << pair.back();  // No matching member function for 'back'.
  }
}

Run Code Online (Sandbox Code Playgroud)

我也用矢量尝试过,它按预期工作。

c++ std-ranges c++23

4
推荐指数
1
解决办法
159
查看次数

了解带有临时参数和纯右值参数的 std::ranges::sort 的返回类型

我在理解类型何时推导出std::ranges::dangling何时使用命名局部变量与纯右值作为std::ranges::sort算法的参数时遇到问题。例如,我有一个函数将 a 返回prvalue 到标准容器,比如 std::vector ,我直接将其用作 的参数std::ranges::sort,然后我期望std::ranges::dangling在尝试取消引用迭代器时收到编译错误,这就是我得到的:

#include <vector>
#include <algorithm>

auto get_data(){
    return std::vector<int>{1, 2, 99, 5, 9, 4};
}

auto get_sorted(){
    return std::ranges::sort(get_data());
}


int main(){
    auto it = get_sorted();
    *(it-1); //Compiler Error because it is a std::ranges::dangling iterator
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我稍微更改get_sorted上面的函数以首先捕获命名变量中的向量并使用它来返回 的结果std::ranges::sort,那么我不会得到悬空迭代器,即使main命名变量中分配的向量应该是函数get_sorted返回后销毁:

auto get_sorted(){
    auto vec = get_data();
    return std::ranges::sort(vec);
}


int main(){
    auto it = get_sorted();
    *(it-1); //Okay result  = …
Run Code Online (Sandbox Code Playgroud)

c++ sorting c++20 prvalue std-ranges

4
推荐指数
1
解决办法
171
查看次数

为什么标准将bored_subrange_t定义为common_range?

C++20 引入了ranges::borrowed_range,它定义了范围的要求,以便函数可以按值获取它并返回从中获得的迭代器,而不会出现悬空的危险。简而言之(参考P2017R1):

当范围超出范围后您可以保留其迭代器时,该范围是借用范围。

同时,borrowed_subrange_t还引入了类型助手:

template<ranges::range R>
using borrowed_subrange_t = std::conditional_t<
    ranges::borrowed_range<R>,
    ranges::subrange<ranges::iterator_t<R>>, 
    ranges::dangling
>;
Run Code Online (Sandbox Code Playgroud)

这是一个别名模板,由一些受限算法(例如ranges::unique和 )使用ranges::find_end,以避免返回潜在的悬空迭代器或视图。

当类型为Rmodels时borrowed_rangeborrowed_subrange_tofR基本上是 a subrange<ranges::iterator_t<R>>,这意味着它也是 a ranges::common_range,因为它只接受一个模板参数,并且第二个默认与第一个参数的类型相同。

但似乎存在一些误导,因为有些subrange类型可以借用但仍然是 not common_range,请考虑以下代码:

auto r = views::iota(0);
auto s1 = ranges::subrange{r.begin(),     r.begin() + 5};
auto s2 = ranges::subrange{r.begin() + 5, r.end()};
Run Code Online (Sandbox Code Playgroud)

subrange从 a 创建两个 s borrowed_range ranges::iota_view,一个包含前 5 个元素,另一个包含itoa_view从第五个元素开始的所有元素。它们是subrange的 …

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

3
推荐指数
1
解决办法
578
查看次数

c++20 范围的意义是什么?

我很难理解 c++20 范围与老式迭代器相比增加了什么。是的,我想不再需要使用beginand end,而是简单的重载,例如:

namespace std {
    template <typename Container>
    auto transform(Container&& container, auto&&... args) requires ( requires {container.begin(); container.end(); }) {
         return transform(container.begin(), container.end(), args...);
    }
}
Run Code Online (Sandbox Code Playgroud)

会解决这个问题。

为什么范围很有用?与迭代器相比,我什么时候应该使用它们?

编辑:我知道范围比迭代器还有其他优点(链接、更好的方法等......)。然而,这些(我认为?)都可以用迭代器来完成,我不明白为什么需要引入一个全新的概念,比如范围。

c++ iterator c++20 std-ranges

3
推荐指数
1
解决办法
2304
查看次数

The real purpose of C++20 keys_view and values_view?

C++20 introduced ranges::elements_view, which accepts a view of tuple-like values, and issues a view with a value-type of the Nth element of the adapted view's value-type, where N is the non-type template parameter.

In [range.elements.view], the synopsis of ranges::elements_view is defined as:

template<input_­range V, size_t N>
  requires view<V> && has-tuple-element<range_value_t<V>, N> &&
           has-tuple-element<remove_reference_t<range_reference_t<V>>, N> &&
           returnable-element<range_reference_t<V>, N>
class elements_view : public view_interface<elements_view<V, N>> {
  public:
    elements_view() = default;
    constexpr explicit elements_view(V base);
  // ...
};
Run Code Online (Sandbox Code Playgroud)

Since …

c++ c++20 std-ranges

3
推荐指数
1
解决办法
161
查看次数

为什么我不能将这个转换后的 directory_iterator 插入到一个向量中?

我正在尝试使用其insert(const_iterator pos, InputIt first, InputIt last)成员函数模板将转换后的目录条目范围插入向量中。不幸的是,我无法在 GCC 下编译以下代码,11.1.0根据https://en.cppreference.com/w/cpp/compiler_support应该有范围支持。

#include <filesystem>
#include <vector>
#include <ranges>
#include <iterator>

namespace fs = std::filesystem;
namespace ranges = std::ranges;
namespace views = std::views;

// no solution
namespace std {
    template <typename F>
    struct iterator_traits<ranges::transform_view<ranges::ref_view<fs::directory_iterator>, F>> {
        using iterator_category = std::input_iterator_tag;
    };
}

int main() {
    std::vector<fs::path> directory_tree;

    auto subdir = fs::directory_iterator(".");
    ranges::input_range auto subdir_names = subdir
        | views::transform([](const auto& entry) { return entry.path(); /* can be more complex*/ }) …
Run Code Online (Sandbox Code Playgroud)

c++ stdvector c++20 std-filesystem std-ranges

3
推荐指数
1
解决办法
104
查看次数