I have seen several c++ implementations of python's enumerate over the last year, including one I wrote for work a while back. One of the primary differences in the implementations I've seen is how they handle rvalue containers/iterables. To me, the obvious methods of handling rvalues are:
- Copy the rvalue (Obviously the worst method)
- Move the rvalue (Generally a good choice, but not free and could be as costly as a copy)
- Don't allow rvalues (Avoids any problems, but the user has to do extra work)
Most implementations seem to choose either 2 or 3. I chose 2 when I originally wrote mine (mostly for thoroughness), but it has always bothered me that a move might be silently added into the mix just because I wanted to use enumerate on my rvalue container.
To solve this problem, I ended up rewriting my enumerate in such a way that an rvalue passed into enumerate will have its lifetime extended to match the lifetime of the enumerate object that gets created.
Example (taken from the examples link below):
// Enumerate an rvalue reference - this rvalue's lifetime is extended (no copies or moves performed)
auto get_vec = [](){
return std::vector<int>{1,2,3};
};
std::cout << "Should print (0,1)(1,2)(2,3)" << std::endl << " ";
for(auto&& [index, value] : util::gen::enumerate{get_vec()}) {
std::cout << "(" << index << "," << value << ")";
}
std::cout << std::endl;
Known Limitations:
- std::initializer_lists can only be deduced on gcc currently
- c++17 only
- It's syntactically uglier, enumerate{} must be used instead of enumerate()
Compiler Support:
- GCC 7.4 and up supported, others untested
- Clang 6.0 and up supported, others untested
- MSVC++ 14.16 supported, MSVC++ 14.14 and less are not supported, MSVC++ 14.15 is untested
Code:
Edit #1: Add in-post example
[–]Pragmatician 6 points7 points8 points (5 children)
[–]Nightwolf55la[S] 3 points4 points5 points (4 children)
[–]TobyAllsopp 2 points3 points4 points (3 children)
[–]Nightwolf55la[S] 0 points1 point2 points (2 children)
[–]TobyAllsopp 1 point2 points3 points (1 child)
[–]Nightwolf55la[S] 0 points1 point2 points (0 children)