标签: std-ranges

C++20 范围太多 | 运营商?

我正在为此代码使用 g++ 10.2。没有任何人知道为什么我得到一个编译错误在过去std::views::reverseresults3

#include <vector>
#include <ranges>

int main() {
    auto values = std::vector{1,2,3,4,5,6,7,8,9,10};
    auto even = [](const auto value) {
        return value % 2 == 0;
    };
    auto square = [](const auto value) {
        return value * value;
    };

    auto results1 = values
        | std::views::filter(even)
        | std::views::reverse
        | std::views::take(4)
        | std::views::reverse;

    auto results2 = values
        | std::views::transform(square)
        | std::views::reverse
        | std::views::take(4)
        | std::views::reverse;

    auto results3 = values
        | std::views::filter(even)
        | std::views::transform(square)
        | std::views::reverse
        | std::views::take(4) …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors c++20 std-ranges

38
推荐指数
2
解决办法
2900
查看次数

为什么 std::ranges::filter_view 对象必须是非常量才能查询其元素?

#include <ranges>
#include <iostream>
#include <string_view>

using namespace std::literals;

int main()
{
    auto fn_is_l = [](auto const c) { return c == 'l'; };

    {
        auto v = "hello"sv | std::views::filter(fn_is_l);
        std::cout << *v.begin() << std::endl; // ok
    }

    {
        auto const v = "hello"sv | std::views::filter(fn_is_l);
        std::cout << *v.begin() << std::endl; // error
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅:https : //godbolt.org/z/vovvT19a5

<source>:18:30: error: passing 'const std::ranges::filter_view<
                       std::basic_string_view<char>, main()::
                       <lambda(auto:15)> >' as 'this' argument discards
                       qualifiers [-fpermissive]
   18 |         std::cout << *v.begin() …
Run Code Online (Sandbox Code Playgroud)

c++ standards constants c++20 std-ranges

30
推荐指数
2
解决办法
694
查看次数

const 是否被 std::views 破坏了?

void foo(const auto& collection)
{
    *collection.begin() = 104;
}

int main()
{
    std::vector<int> ints {1, 2, 3, 4, 5};
    foo(ints); // Error, as it should be
    foo(ints | std::views::all); // Compiles and modifies the vector. Why?
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果函数的参数是类型,为什么左值引用的常量性会被完全忽略std::view

编辑:
如果,正如您在注释中所写,const 视图引用与此上下文中的 const 指针类似,那么如果同一函数采用从右值对象构造的视图作为参数,为什么代码无法编译?

std::vector<int> getVec()
{
    return std::vector{1, 2, 3, 4, 5};
}

void foo(const auto& collection)
{
    *collection.begin() = 104; // Error: assignment of read-only location
}

int main()
{
    foo(getVec() | std::views::all); // Nope! …
Run Code Online (Sandbox Code Playgroud)

c++ constants c++20 std-ranges

28
推荐指数
1
解决办法
1479
查看次数

Why is iterating over std::ranges::views::join so slow

This is a follow-up of this SO Answer. Given a flat input range and three size_t dimensions, the code creates a nested random_access_range of random_access_ranges of random_access_ranges, modelling a three-dimensional array.

在此输入图像描述 Quickbench

Iterating over the elements in the "multidimensional" range using a nested-for loop and indices is a bit slower than directly iterating over the elements of the input range (factor 4 slower). I suppose some performance drop can be expected, but a factor of 4 hurts …

c++ benchmarking c++20 std-ranges

26
推荐指数
1
解决办法
1450
查看次数

为什么 std::views::split() 编译但不使用未命名字符串文字作为模式进行拆分?

std::views::split()获取未命名的字符串文字作为模式时,它不会分割字符串,但可以很好地处理未命名的字符文字。

#include <iomanip>
#include <iostream>
#include <ranges>
#include <string>
#include <string_view>

int main(void)
{
    using namespace std::literals;

    // returns the original string (not splitted)
    auto splittedWords1 = std::views::split("one:.:two:.:three", ":.:");
    for (const auto word : splittedWords1)
        std::cout << std::quoted(std::string_view(word));
    
    std::cout << std::endl;

    // returns the splitted string
    auto splittedWords2 = std::views::split("one:.:two:.:three", ":.:"sv);
    for (const auto word : splittedWords2)
        std::cout << std::quoted(std::string_view(word));
    
    std::cout << std::endl;

    // returns the splitted string
    auto splittedWords3 = std::views::split("one:two:three", ':');
    for (const auto word : …
Run Code Online (Sandbox Code Playgroud)

c++ split string-literals std-ranges c++23

23
推荐指数
2
解决办法
2115
查看次数

为什么 std::vector 不能接受 size_t 类型的 iota_view 迭代器?

以下代码在nis时无法编译,但在和size_t时运行良好。intunsigned

#include <vector>
#include <ranges>

int main() {
    size_t n = 1;
    auto view = std::ranges::iota_view{n, n};
    std::vector test(view.begin(), view.end()); //std::vector dislikes these iterators
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/a3eGeMWqh

c++ iterator c++20 std-ranges

20
推荐指数
2
解决办法
1665
查看次数

为什么 range::for_each 返回该函数?

传统的std::for_each返回函数作为标准需要根据[alg.foreach]Function满足Cpp17MoveConstructible

\n
\n
template<class InputIterator, class Function>\n  constexpr Function for_each(InputIterator first, InputIterator last, Function f);\n
Run Code Online (Sandbox Code Playgroud)\n

前提条件Function满足Cpp17MoveConstructible要求。

\n

[注意:\xe2\x80\x82Function不需要满足Cpp17CopyConstructible的要求。尾注]

\n
\n

这是合理的,因为用户可能希望在调用后重用该函数。

\n

的并行版本for_each没有返回:

\n
\n
template<class ExecutionPolicy, class ForwardIterator, class Function>\n  void for_each(ExecutionPolicy&& exec,\n                ForwardIterator first, ForwardIterator last,\n                Function f);\n
Run Code Online (Sandbox Code Playgroud)\n

前提条件Function满足Cpp17CopyConstructible要求。

\n
\n

这是因为标准要求Function满足Cpp17CopyConstructible,因此不需要返回该函数,因为用户可以根据需要在调用方自由创建副本。

\n

我注意到ranges::for_each …

c++ language-design language-lawyer c++20 std-ranges

20
推荐指数
2
解决办法
1769
查看次数

我们真的需要将范围适配器隐式转换为 bool 吗?

由于ranges::view_interface有一个explicit operator bool()函数,这使得大多数 C++20 范围适配器能够转换为bool

https://godbolt.org/z/ccbPrG51c

static_assert(views::iota(0));
static_assert("hello"sv | views::split(' '));
static_assert(views::single(0) | std::views::transform([](auto) { return 0; }));
Run Code Online (Sandbox Code Playgroud)

虽然这看起来很方便,但我们真的需要这个功能吗?原因是传统的STL容器比如std::vector,或者常用的视图比如std::string_view,没有这个转换为 的功能bool,看起来有些不协调。只是调用.empty()ranges::empty直接确定范围是否为空似乎更直观。

此外,这种隐式转换也可能会引起混淆:

static_assert(!views::empty<int>);
Run Code Online (Sandbox Code Playgroud)

那么,为什么ranges::view_interface提供这个operator bool功能呢?有没有实际的用例?

请注意,这可能是一个基于意见的问题,但我想知道view_interface提供operator bool.

c++ c++20 std-ranges

19
推荐指数
1
解决办法
405
查看次数

擦除-删除习语如何与范围/受限算法一起使用?

我正在尝试将 c++20 约束算法用于擦除删除习语:

std::vector<int> v;
v.erase(std::unique(std::begin(v), std::end(v)), std::end(v));
Run Code Online (Sandbox Code Playgroud)

但是当我做一个简单的转换时:

v.erase(std::ranges::unique(v), std::end(v));
Run Code Online (Sandbox Code Playgroud)

我收到一个错误,参数erase不匹配:

error: no matching function for call to 'std::vector<int>::erase(std::ranges::borrowed_subrange_t<std::vector<int>&>, std::vector<int>::iterator)'
Run Code Online (Sandbox Code Playgroud)

如果第二个参数是 ,则会产生类似的错误std::ranges::end(v)

我怎样才能让它发挥作用?


该问题最初使用remove而不是unique,但是std::erase所有容器都过载了,这使得该特定用例的动机降低。

c++ c++20 std-ranges

18
推荐指数
3
解决办法
709
查看次数

范围适配器的开始/结束的常量过载是否受到限制?

在 C++20 中,某些范围同时具有const和 non- const begin()/end(),而其他范围仅具有 non- const begin()/end()

\n

为了使包装前者的范围适配器能够begin()/end()在合格时使用const,一些范围适配器如elements_viewreverse_viewcommon_view都提供了 constrainedconst合格的begin()/end()函数,例如:

\n
 template<view V>\n   requires (!common_\xc2\xadrange<V> && copyable<iterator_t<V>>)\n class common_view : public view_interface<common_view<V>> {\n  public:\n   constexpr auto begin();\n   constexpr auto end();\n\n   constexpr auto begin() const requires range<const V>;\n   constexpr auto end()   const requires range<const V>;\n};\n\ntemplate<input_\xc2\xadrange V, size_t N>\n  requires view<V> && has-tuple-element<range_value_t<V>, N>\nclass elements_view : public view_interface<elements_view<V, N>> {\n public:\n  constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++20 std-ranges

17
推荐指数
1
解决办法
699
查看次数