我有一个价值观的集合:
auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
Run Code Online (Sandbox Code Playgroud)
我想在这个值集合上应用遵循以下条件的视图:
这是我尝试过的视图:
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)
但执行甚至没有进入打印循环,因为视图是空的。我的猜测是所有标准都会立即应用:
我所期待的:
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它来压平它,但我收到了错误
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\nRun Code Online (Sandbox Code Playgroud)\n我已经尝试过以下操作:
\nfor (auto it : planters){\n plants.insert(plants.end(), it.getPlants().begin(), it.getPlants().end());\n}\nRun Code Online (Sandbox Code Playgroud)\n这是可行的,但是我只允许使用一个循环(不包括 STL 函数调用内的循环)并且只能分配内存一次。上述方法多次分配内存。我该如何处理这个问题?
\n我的代码:
\nstd::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) 如果我想按字典顺序比较两个向量,我可以这样做:
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
我知道如何使用 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.find和string.replace,但想使用范围。
C++23 引入了范围视图std::generator,用作协程的返回。根据以前的观点,通常很难生成复杂的数据序列。我认为使用协程可以大大简化这一过程。
不幸的std::generator是,目前没有任何标准库实现,并且在许多项目中,C++20 将在一段时间内保持标准。std::generator有没有办法在C++20项目中使用?
我得到了一个随机整数向量v,并希望按照以下标准分成子范围:
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库的替代方法?
让我们有一个嵌套循环:
#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) 我正在尝试使引用包装器与异构搜索一起使用,并使其符合范围。这是我想要工作的片段:
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++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++20 中,新的命名空间std::ranges被添加到标准中,其中许多算法复制了现有的算法,例如std::find_if和std::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。那么有什么区别,在什么情况下我应该选择哪一个呢?