I'm trying to use views in a commercial application, and noticed an inconsistency between gcc and Visual Studio.
In the code below, calling transformed()
twice returns two different, apparently incompatible views. In gcc 11 (on godbolt), the code executes without issue, even with extra debugging, but in Visual Studio 16.11 with -std:c++latest
, it asserts:
cannot compare incompatible transform_view iterators
I would like my function to be callable just as if it were returning a const std::vector<std::pair<int, int>> &
so the caller doesn't have to worry about temporaries. It seems that I could make my transformed view a member of my class, initialize it in the constructor, and return that, but I don't even know how to declare it.
I'm assuming that Visual Studio is correct and my code is illegal, but even if my code should be legal, it still has to work. We have a 10,000,000-line code base and a lot of non-expert C++ programmers, and I need the core to be robust and not have hidden gotchas like this.
#include <iostream>
#include <ranges>
#include <vector>
struct X
{
std::vector<int> m_values{ 1,2,3 };
auto transformed() const
{
return std::ranges::views::transform(m_values, [](int i) {
return std::pair{ i, i + i };
});
}
};
int main()
{
X x;
for (auto [a, b] : x.transformed())
std::cout << a << " " << b << std::endl;
if (x.transformed().begin() != x.transformed().end()) // asserts in visual studio.
std::cout << "not empty";
return 0;
}