字符串向量并使用 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 (experimental) [master revision 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:: ranges 视图指向无效内存。
使用与上述相同的结构处理非字符串工作正常。
似乎是 10.0.1 的错误。
以 Pete 为例并在 10.0.1 上尝试重现该问题。 (无限循环) 。 https://godbolt.org/z/PqdceV 10.1 上的完全相同的代码产生了所需的行为。我想我现在需要坚持使用编译器资源管理器来学习范围。
你的编译器没有问题。您的代码具有未定义的行为。视图是惰性评估的,并且要求在您访问它们时底层容器仍然存在。你所拥有的类似于悬空引用。
{"c", "dddddddd", "aaaa", "bb"}
这里你创建了一个 临时 向量,它在包含调用 f
(a.k.a直到行尾 ;
),所以当你在 for(auto i : v)
中访问 v
时它就死了。在你的范围循环之前,你的 lambda 中的 f.size();
不会被调用。但在这一点上,正如我所说,你的临时向量及其所有字符串元素都不存在了。
为了帮助缓解此类错误,您可以禁止使用临时对象调用 f:
auto f(std::vector<std::string>&& vec) = delete;
以下 C++20 范围基本语法有什么问题 (Ubuntu 20.04, gcc g++ (Ubuntu 10-20200411-0ubuntu1) 10.0.1 20200411 (experimental) [master revision 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:: ranges 视图指向无效内存。
使用与上述相同的结构处理非字符串工作正常。
似乎是 10.0.1 的错误。 以 Pete 为例并在 10.0.1 上尝试重现该问题。 (无限循环) 。 https://godbolt.org/z/PqdceV 10.1 上的完全相同的代码产生了所需的行为。我想我现在需要坚持使用编译器资源管理器来学习范围。
你的编译器没有问题。您的代码具有未定义的行为。视图是惰性评估的,并且要求在您访问它们时底层容器仍然存在。你所拥有的类似于悬空引用。
{"c", "dddddddd", "aaaa", "bb"}
这里你创建了一个 临时 向量,它在包含调用 f
(a.k.a直到行尾 ;
),所以当你在 for(auto i : v)
中访问 v
时它就死了。在你的范围循环之前,你的 lambda 中的 f.size();
不会被调用。但在这一点上,正如我所说,你的临时向量及其所有字符串元素都不存在了。
为了帮助缓解此类错误,您可以禁止使用临时对象调用 f:
auto f(std::vector<std::string>&& vec) = delete;