Почему этот std::view оценивается дважды?C++

Программы на C++. Форум разработчиков
Anonymous
Почему этот std::view оценивается дважды?

Сообщение Anonymous »

У меня есть следующая тестовая программа:

Код: Выделить всё

#include 
#include 
#include 

int main() {
const std::vector 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 vector = std::ranges::to( output );

std::println("\ninput size: {} output size: {}", input.size(), vector.size() );
}
который при компиляции в Xcode 16.2 в режиме C++23 выводит следующее:

Код: Выделить всё

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
Меня это смущает. Почему каждый элемент оценивается дважды при преобразовании в std::vector?
Когда я пытаюсь с помощью простого цикла for напечатать элементы, каждый элемент оценивается только один раз:

Код: Выделить всё

#include 
#include 
#include 

int main() {
const std::vector 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);
}
выходы:

Код: Выделить всё

0 1 2 3 4 5 6 7 8 9 10
sum: 126
Первая программа кажется неэффективной и заставляет меня задуматься, стоит ли мне начинать использовать диапазоны... есть ли лучший способ ее написать?

Подробнее здесь: https://stackoverflow.com/questions/793 ... ated-twice

Вернуться в «C++»