以下 C++20 范围基本语法有什么问题 (Ubuntu 20.04, gcc g++ (Ubuntu 10-20200411-0ubuntu1) 10.0.1 20200411 (实验) [master revision bb87d5cc77d:75961caccb7:f883c46b4877f637e0fa5025b4d6b5c9 040ec566]):
#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;
}
Run Code Online (Sandbox Code Playgroud)
我想获取一个字符串向量并将其转换为每个字符串的大小。
尝试使用 C++11 范围 for 循环进行迭代只会崩溃。在 gdb 中,我可以看到 std::ranges 视图指向无效内存。
使用与上面相同的结构处理非字符串效果很好。
你的编译器没有任何问题。您的代码具有未定义的行为。视图是惰性计算的,并且要求当您访问它们时底层容器仍然处于活动状态。你所拥有的类似于悬空引用。
{"c", "dddddddd", "aaaa", "bb"}在这里,您创建一个临时向量,该向量在包含调用的完整表达式的末尾处终止f(也称为直到行尾;),因此当您访问 时它就终止v了for(auto i : v)。f.size();在 for range 循环之前,不会调用 lambda 中的。但此时正如我所说,临时向量及其所有字符串元素不再存在。
为了帮助减轻这种错误,您可以禁止使用临时变量调用 f:
auto f(std::vector<std::string>&& vec) = delete;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |