简体   繁体   中英

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]):

#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. In gdb, I can see that the std:: ranges view is pointing to invalid 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) . The f.size(); from your lambda is not called until your for range loop. 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:

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

Seems like a 10.0.1 bug. taking Pete's example and trying it out on 10.0.1 reproduce the issue. (infinite loop). Exact same code on https://godbolt.org/z/PqdceV 10.1 produced the desired behavior. I guess I'd need to stick to compiler explorer for now to learn ranges.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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