简体   繁体   English

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

[英]vector of strings and transform with C++20 ranges

What is wrong in the following C++20 ranges basic syntax (Ubuntu 20.04, gcc g++ (Ubuntu 10-20200411-0ubuntu1) 10.0.1 20200411 (experimental) [master revision bb87d5cc77d:75961caccb7:f883c46b4877f637e0fa5025b4d6b5c9040ec566]): What is wrong in the following C++20 ranges basic syntax (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;
}

I'd like to take a vector of strings and transform it to the size of each string.我想获取一个字符串向量并将其转换为每个字符串的大小。

Trying to iterate with C++11 range for-loop is just crashing.尝试使用 C++11 范围 for-loop 进行迭代只会崩溃。 In gdb, I can see that the std:: ranges view is pointing to invalid memory.在 gdb 中,我可以看到 std::ranges 视图指向无效的 memory。

Dealing with non string using same constructs as above works fine.使用与上述相同的结构处理非字符串可以正常工作。

There is nothing wrong with your compiler.你的编译器没有问题。 Your code has Undefined Behavior.您的代码具有未定义的行为。 Views are lazy evaluated and require that the underlying container is still alive when you access them.视图是惰性评估的,并且要求在您访问它们时底层容器仍然处于活动状态。 What you have is akin to a dangling reference.你所拥有的类似于一个悬空的参考。

{"c", "dddddddd", "aaaa", "bb"} Here you create a temporary vector which dies at the end of the full expression containing the call to f (aka until the end of the line ; ) and so it dies by the time you access v in for(auto i: v) . {"c", "dddddddd", "aaaa", "bb"}在这里,您创建一个临时向量,该向量在包含对f的调用的完整表达式的末尾终止(也就是直到行尾; ),所以它当您在for(auto i: v)中访问v时死亡。 The f.size(); f.size(); from your lambda is not called until your for range loop.从你的 lambda 直到你的 for range 循环才会被调用。 But at this point as I've said you temporary vector with all of its string elements don't exist anymore.但是在这一点上,正如我所说的,你的所有字符串元素的临时向量都不存在了。

To help mitigate this kind of bug you can prohibit calling f with temporaries:为了帮助减轻这种错误,您可以禁止使用临时调用 f:

auto f(std::vector<std::string>&& vec) = delete;

Seems like a 10.0.1 bug.似乎是一个 10.0.1 错误。 taking Pete's example and trying it out on 10.0.1 reproduce the issue.以 Pete 的示例并在 10.0.1 上尝试重现该问题。 (infinite loop). (无限循环)。 Exact same code on https://godbolt.org/z/PqdceV 10.1 produced the desired behavior. https://godbolt.org/z/PqdceV 10.1 上完全相同的代码产生了所需的行为。 I guess I'd need to stick to compiler explorer for now to learn ranges.我想我现在需要坚持使用编译器资源管理器来学习范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM