标签: std-ranges

如何在始终选择第一个元素并过滤其余元素的范围内创建视图?

我有一个价值观的集合:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
Run Code Online (Sandbox Code Playgroud)

我想在这个值集合上应用遵循以下条件的视图:

  • 应始终选择第一个元素。
  • 从下一个元素中,仅选择偶数,直到...
  • ...查找等于或大于 6 的元素。

这是我尝试过的视图:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
auto r = v |
    std::views::take(1) |
    std::views::filter([](const int x) { return !(x & 1); }) |
    std::views::take_while([](const int x) { return x < 6; });

for (const auto &x : r)
    std::cout << x << ' ';
Run Code Online (Sandbox Code Playgroud)

但执行甚至没有进入打印循环,因为视图是空的。我的猜测是所有标准都会立即应用:

  1. 选择第一个元素 (43)。
  2. 是奇数。
  3. 观看结束。

我所期待的:

  1. 选择第一个元素而不检查任何内容。
  2. 从其余元素中,仅过滤偶数 …

c++ c++20 std-ranges

2
推荐指数
1
解决办法
936
查看次数

展平包含结构向量的类向量

Planters我有一个包含 s 向量的类向量Plant。我的目标是返回一个植物向量,其中包含来自 Planter 1 的植物,然后是来自 Planter 2 的植物,依此类推。\n示例:planter{{1,2,3,4}, {2,3,4,5}}应该导致{1,2,3,4,2,3,4,5}. 请注意,数字代表植物对象。我试图用join_view它来压平它,但我收到了错误

\n
error: class template argument deduction failed:\n   18 |         plants = std::ranges::join_view(planterView);\n      |                                                    ^\n/home/parallels/CMPT373/se-basic-cpp-template/lib/solutions/task05.cpp:18:52: error: no matching function for call to \xe2\x80\x98join_view(std::ranges::ref_view<std::vector<ex4::Planter> >&)\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n

我已经尝试过以下操作:

\n
for (auto it : planters){\n  plants.insert(plants.end(), it.getPlants().begin(), it.getPlants().end());\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是可行的,但是我只允许使用一个循环(不包括 STL 函数调用内的循环)并且只能分配内存一次。上述方法多次分配内存。我该如何处理这个问题?

\n

我的代码:

\n
std::vector<Plant> task05(std::vector<Planter> planters){\n    std::vector<Plant> plants;\n    auto planterView = std::views::all(planters);\n    std::views::transform(planterView, [](Planter planter){ return planter.getPlants();});\n    plants = ranges::views::all(std::ranges::join_view(planterView));\n    return plants;\n}\n …
Run Code Online (Sandbox Code Playgroud)

c++ stl-algorithm c++20 std-ranges

2
推荐指数
1
解决办法
205
查看次数

如何按字典顺序按相反顺序比较两个向量?

如果我想按字典顺序比较两个向量,我可以这样做:

int main() {
    std::vector<int> a{0, 7, 8, 9};
    std::vector<int> b{1, 2, 3, 4};

    std::cout << std::boolalpha;
    std::cout << "a < b returns " << (a < b) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

但是以相反的顺序执行相同的操作无法编译:

int main() {
    std::vector<int> a{3, 2, 1};
    std::vector<int> b{9, 8, 7, 6};

    std::cout << std::boolalpha;
    std::cout << "revrese a < reverse b returns " << ((a | std::views::reverse) < (b | std::views::reverse)) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

后一个代码失败并显示:

<source>:23:81: error: no match for 'operator<' (operand types are 'std::ranges::reverse_view<std::ranges::ref_view<std::vector<int> > >' …
Run Code Online (Sandbox Code Playgroud)

c++ vector comparison-operators lexicographic-ordering std-ranges

2
推荐指数
1
解决办法
348
查看次数

如何使用 C++ std::ranges 替换字符串中的子字符串?

我知道如何使用 std::replace 替换向量中的字符,如下所示:ranges::replace

我会撒谎对字符串中的子字符串做类似的事情。例如:

std::string str{"The quick brown fox jumped over the lazy dog.";
std::ranges::replace(str, "the", "a");
Run Code Online (Sandbox Code Playgroud)

但我收到一个错误:

错误:与调用 '(const std::ranges::__replace_fn) (std::string&, const char [4], const char [2])' 不匹配

或者如果我使用字符串

错误:与调用 '(const std::ranges::__replace_fn) (std::string&, std::string&, std::string&)' 不匹配

它适用于字符,但不适用于子字符串。

有任何想法吗?

我已成功使用循环 andstring.findstring.replace,但想使用范围。

c++ string replace c++20 std-ranges

2
推荐指数
1
解决办法
1478
查看次数

我可以在 C++20 项目中使用 std::generator 来生成范围视图吗?

C++23 引入了范围视图std::generator,用作协程的返回。根据以前的观点,通常很难生成复杂的数据序列。我认为使用协程可以大大简化这一过程。

不幸的std::generator是,目前没有任何标准库实现,并且在许多项目中,C++20 将在一段时间内保持标准。std::generator有没有办法在C++20项目中使用?

c++ c++20 c++-coroutine std-ranges c++23

2
推荐指数
1
解决办法
1596
查看次数

使用 range::views::chunk_by 时可以引用当前子范围吗?

我得到了一个随机整数向量v,并希望按照以下标准分成子范围:

  1. 子范围中的整数应该是连续的并且加 1(易于检查)
  2. 子范围的大小不应大于 4(这很难)
auto result = v | ranges::views::chunk_by([](int a, int b) {
 return a + 1 == b /* && size of current chunk < 4 */;
});
Run Code Online (Sandbox Code Playgroud)

有谁知道如何做到这一点?有没有仍然使用ranges库的替代方法?

c++ std-ranges

2
推荐指数
1
解决办法
257
查看次数

在访问所有上下文时用 std::ranges 替换嵌套循环

让我们有一个嵌套循环:

#include <string>
#include <vector>
#include <iostream>

struct Account {
    int money;
};

struct Person {
    std::string name;
    std::vector<Account> accounts;
};

int main()
{
    std::vector<Person> persons;

    for(const auto& iPerson: persons) {
        for(const auto& iAccount: iPerson.accounts) {
            std::cout << iPerson.name << ": " << iAcount.money << std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何将其替换为std::ranges::view以便可以访问 Person 和 Account。这里有一个类似的问题:用 std::ranges 摆脱嵌套的 for 循环。但在这种情况下,还需要对外部循环人员的引用

我期望的是来自所有循环级别的对象的某种引用元组

auto person_account_view = persons | //...create tuple view;
for(const auto& iPersonAccount: person_account_view) {
    const auto& name = std::get<0>().name; …
Run Code Online (Sandbox Code Playgroud)

c++ std-ranges

2
推荐指数
1
解决办法
215
查看次数

如何使 range::binary_search (特别是异构搜索)与引用一起使用

我正在尝试使引用包装器与异构搜索一起使用,并使其符合范围。这是我想要工作的片段:

struct addressable { int address; };

template <typename T>
struct ref : std::reference_wrapper<T> {
    // comparisons for heterogeneous search
}

template <typename T>
ref<T> wrap_ref(T& value) { return {value}; }

int main() {
    const std::vector<addressable> nums { {1}, {2}, {3}, {4}, {5}, {6} };
    ref_vec<const addressable> num_refs;
    for (const auto& num : nums) { num_refs.push_back(wrap_ref(num)); }
    const auto found = std::ranges::binary_search(num_refs, 2); // doesn't work
}
Run Code Online (Sandbox Code Playgroud)

异构搜索对于经典std算法来说工作得很好(对于它们来说,实现<和就足够了==。现在,ranges它们有更严格的要求,所以我尝试通过以下方式实现强排序操作:

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

c++ c++20 std-ranges

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

如何从 std::chunk_by 返回值获取各个块?

我有以下 c++23 代码,它使用gcc-13.2.

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

auto main() -> int
{
    using std::cout;
    std::vector<int> v{1,2,2,2,1,1,1,2,1};
    auto chunks = v | std::views::chunk_by(std::equal_to{});
    for (auto chunk : chunks)
    {
        cout << "[";
        for (const auto& value : chunk)
        {
            cout << value << ", ";
        }
        cout << "]\n";
    }
    cout << std::flush;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印

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

正如预期的那样。

但我只想获取该列表 ( [2, 2, 2, …

c++ std-ranges c++23

2
推荐指数
1
解决办法
93
查看次数

C++ 算法中的“函数”和“类函数实体”有什么区别?

在 C++20 中,新的命名空间std::ranges被添加到标准中,其中许多算法复制了现有的算法,例如std::find_ifstd::ranges::find_if。在cppreference 页面上,“旧”算法被称为“函数”,“新”算法被称为“类函数实体”。然而,我不能以“功能”的方式使用它,例如

auto result = myMapObj
                | std::ranges::views::keys
                | std::ranges::find_if([](const auto& key) { return key == 42; });
Run Code Online (Sandbox Code Playgroud)

我需要像旧的一样使用它std::find_if。那么有什么区别,在什么情况下我应该选择哪一个呢?

c++ c++20 std-ranges

2
推荐指数
1
解决办法
124
查看次数