字符串的矢量并使用 C++20 范围进行转换
vector of strings and transform with C++20 ranges
以下 C++20 范围基本语法(Ubuntu 20.04、gcc g++ (Ubuntu 10-20200411-0ubuntu1( 10.0.1 20200411(实验性([主修订版 bb87d5cc77d:75961caccb7:f883c46b4877f637e0fa5025b4d6b5c9040ec566](:
#include <iostream>
#include <vector>
#include <ranges>
[[nodiscard]]
auto f(const std::vector<std::string>& vec) {
return vec | std::views::transform([] (const std::string &f){
return f.size(); });
}
int main() {
const auto v = f({"c", "dddddddd", "aaaa", "bb"});
for(auto i : v)
std::cout << i << ' ';
std::cout << 'n';
return 0;
}
我想获取一个字符串向量并将其转换为每个字符串的大小。
尝试使用 C++11 范围的 for 循环进行迭代只是崩溃。 在 gdb 中,我可以看到 std:: 范围视图指向无效内存。
使用与上述相同的结构处理非字符串可以正常工作。
你的编译器没有错。您的代码具有未定义的行为。视图是延迟计算的,并且要求在访问它们时基础容器仍处于活动状态。你所拥有的类似于一个悬而未决的参考。
{"c", "dddddddd", "aaaa", "bb"}
在这里,您创建一个临时向量,该向量在包含对f
调用的完整表达式的末尾死亡(也称为直到行;
的末尾(,因此当您在for(auto i : v)
中访问v
时,它就会死亡。在 for 范围循环之前,不会调用来自 lambda 的f.size();
。但是在这一点上,正如我所说,临时向量及其所有字符串元素不再存在。
为了帮助缓解此类错误,您可以禁止使用临时调用 f:
auto f(std::vector<std::string>&& vec) = delete;
看起来像一个 10.0.1 错误。 以皮特为例并在 10.0.1 上尝试重现该问题。(无限循环( .https://godbolt.org/z/PqdceV 10.1 上的完全相同的代码产生了所需的行为。我想我现在需要坚持使用编译器资源管理器来学习范围。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 用C++20 fmt限制结果的总大小
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何在C++20中创建模板别名的推导指南
- 在基于范围的for循环中使用结构化绑定声明
- 实施具有 C++20 概念的配对概念
- 如何计算数据类型的范围,例如int
- 将 C++20 范围与istreambuf_iterator一起使用
- 在 C++20 中将多个范围适配器连接到一个范围中
- 字符串的矢量并使用 C++20 范围进行转换
- 递归应用 C++20 范围适配器会导致编译时无限循环
- 为什么 C++20 范围不只提供管道语法?
- 在 C++20 计算范围内相邻对的最简洁明了的方法是什么?
- 迭代器的范围 TS 和 C++20 概念是否需要能够使用"运算符>"?
- C++20 范围的切片视图
- 我将如何传递范围而不是C 20中的迭代对对
- 是 GCC 6.2 或更高版本中的 C++20 实验范围