字符串的矢量并使用 C++20 范围进行转换

vector of strings and transform with C++20 ranges

本文关键字:范围 C++20 转换 字符串      更新时间:2023-10-16

以下 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 上的完全相同的代码产生了所需的行为。我想我现在需要坚持使用编译器资源管理器来学习范围。