El uso del operador ‘|’ (pipe) con std::views no se compila.
Después de una desviación en su carrera, estoy intentando ponerme al día con std::views (y la programación funcional en general). Estoy usando el operador ‘|’ (pipe) con std::views::filter en un vector, y estoy confundido por qué algunas estructuras de código se compilan y otras no.
Este código crea un vector de vectores de int
, luego los filtra por su suma. He comentado las tres declaraciones que me confunden, las dos primeras de las cuales se compilan y la tercera no.
El error de compilación es:
‘ | ‘: no se encontró el operador que tome un operando izquierdo del tipo ‘std::vector
(Usando MSVC19, compilado con ‘/std:c++latest’)
Estoy confundido por qué esto no se compila mientras que (2) especialmente sí lo hace?
#include
#include
#include
template
auto buildMultiples(const std::vector
{
std::vector<>
for(T n= 1; n <= 5; n++)
{
auto v = base;
for (auto& m : v) m *= n;
vRet.push_back(v);
}
return vRet;
}
template
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
auto mults = buildMultiples(nums);
for (auto& m : buildMultiples(nums)) {} //1. Compila
sumGreaterThan<int> sumFilter{ 10 };
auto vecs = buildMultiples(nums);
for (auto& m : vecs | views::filter(sumFilter)) {} //2. Compila
for (auto& m : buildMultiples(nums) | views::filter(sumFilter)) {} //3. ¡Error de compilación!
for (auto vecs = buildMultiples(nums); auto& m : vecs | views::filter(sumFilter)) {} // 4. Compila. Gracias @Aryter
}
davy.ai
La razón por la cual la tercera declaración no compila es porque el operador pipe (
|
) tiene una precedencia mayor que el operador punto (.
). Esto significa quebuildMultiples(nums) | views::filter(sumFilter)
es tratado como(buildMultiples(nums) | views::filter)(sumFilter)
, lo cual no es lo que queremos. Queremos filtrar el resultado debuildMultiples(nums)
y no filtrarbuildMultiples(nums)
en sí.Para arreglar esto, necesitamos agrupar la expresión
buildMultiples(nums)
utilizando paréntesis de esta manera:Esto filtrará correctamente el resultado de
buildMultiples(nums)
y el código compilará.Alternativamente, podemos asignar el resultado de
buildMultiples(nums)
a una variable y luego filtrar la variable de esta manera:Esto también filtrará correctamente el resultado y el código compilará.