Tenho o seguinte programa de teste:
#include <vector>
#include <print>
#include <ranges>
int main() {
const std::vector<int> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto output = input
| std::views::filter([](const int n) { std::print("{} ", n); return n % 3 == 0; })
| std::views::transform([](const int n) {return n * n; });
const std::vector<int> vector = std::ranges::to<std::vector>( output );
std::println("\ninput size: {} output size: {}", input.size(), vector.size() );
}
que, quando compilado no Xcode 16.2 com modo c++23, produz isto:
0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10
input size: 11 output size: 4
Estou confuso com isso. Por que cada item é avaliado duas vezes ao ser convertido para std::vector?
Quando tento um for
ciclo simples para imprimir os elementos, cada item é avaliado apenas uma vez:
#include <vector>
#include <print>
#include <ranges>
int main() {
const std::vector<int> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto output = input
| std::views::filter([](const int n) { std::print("{} ", n); return n % 3 == 0; })
| std::views::transform([](const int n) {return n * n; });
int sum = 0;
for ( int i : output ) sum += i;
std::println("\nsum: {}", sum);
}
saídas:
0 1 2 3 4 5 6 7 8 9 10
sum: 126
O primeiro programa parece ineficiente e me faz reconsiderar se devo começar a usar intervalos... existe uma maneira melhor de escrevê-lo?