After a career diversion, I am trying to get up to speed with std::views (and functional programming in general). I am using the '|' (pipe) operator with std::views::filter on a vector, and I am puzzled why some code structures compile and others don't.
This code creates a vector of vectors of int, then filters them by sum. I've commented the three statements that are confusing me, the first two of which compile and the third doesn't.
Compilation error is:
'|': no operator found which takes a left-hand operand of type 'std::vector<std::vector<int,std::allocator<int>>,std::allocator<std::vector<int,std::allocator<int>>>>' (or there is no acceptable conversion)
(Using MSVC19, compiled with /std:c++latest)
I am puzzled as to why this doesn't compile while (2) especially does?
#include <vector>
#include <numeric>
#include <ranges>
template<typename T>
auto buildMultiples(const std::vector<T>& base)
{
std::vector<std::vector<T>> vRet;
for(T n= 1; n <= 5; n++)
{
auto v = base;
for (auto& m : v) m *= n;
vRet.push_back(v);
}
return vRet;
}
template<typename T>
struct sumGreaterThan
{
T _limit{ 0 };
auto operator()(const std::vector<T>& v) {return std::accumulate(v.cbegin(), v.cend(), 0) > _limit;}
};
int main()
{
using namespace std;
vector<int> nums{1,2,3,4,5,6,7,8,9};
auto mults = buildMultiples(nums);
for (auto& m : buildMultiples(nums)) {} //1. Compiles
sumGreaterThan sumFilter{ 10 };
auto vecs = buildMultiples(nums);
for (auto& m : vecs | views::filter(sumFilter)) {} //2. Compiles
for (auto& m : buildMultiples(nums) | views::filter(sumFilter)) {} //3. Compilation Error!!
for (auto vecs = buildMultiples(nums); auto & m : vecs | views::filter(sumFilter)) {} // 4. Compiles. Thanks @Aryter
}