Замена данных на range-v3

TL;DR

Как можно получить те же результаты, что и

std::copy(std::begin(a), std::end(a), std::begin(b));

используя range-v3 и, возможно, его приятный синтаксис?

ИЗМЕНИТЬ

Причина, по которой у меня возникли проблемы, заключается в непонимании того, как правильно использовать ranges::copy: второй аргумент должен быть итератором, а не объектом range. Моя вина ;)

Тем не менее, я все еще спрашиваю, доступен ли какой-то синтаксический сахар для выполнения ранжированного присваивания, как показано ниже:

ranges::???(b) = a | op1 | op2 | ... ; 

Проблема

У меня есть два вектора фиксированного размера (во время выполнения). Мне нужно выполнить некоторое сложное преобразование данных в первом векторе и сохранить результаты во втором векторе. Мне нужно сохранить первый вектор, и я не хочу создавать новый временный вектор.

Общий код

using namespace std;
vector<double> a;
...
vector<double> b(a.size());

со станд.

transform(begin(a), end(a), begin(b), complexFun);

Гибридный стандарт-rangev3

auto transformation = a | ranges::view::transform(complexFun);
copy(begin(transformation), end(transformation), begin(b));

В этом простом случае в этом нет необходимости. Однако, если задействовано более одной операции, создание представления диапазона с использованием std::copy особенно полезно.

Что я хотел бы написать

ranges::???(b) = a | ranges::view::transform(complexFun);

Я ожидаю, что эта функция уже существует, и я не могу ее найти.


person dodomorandi    schedule 15.12.2017    source источник


Ответы (2)


Есть несколько хороших способов сделать это. Во-первых, если у вас еще нет пункта назначения vector и вы хотите его создать:

auto b = a | ranges::view::transform(complexFun) | ranges::to_vector;

Во-вторых, если у вас уже есть место назначения vector, емкость которого вы хотите повторно использовать:

b.clear(); // Assuming b already contains junk
b |= ranges::action::push_back(a | ranges::view::transform(complexFun));

В обоих случаях range-v3 достаточно умен, чтобы зарезервировать емкость в целевом векторе для ranges::size(a | ranges::view::transform(complexFun)) элементов, чтобы избежать копирования из-за перераспределения.

person Casey    schedule 15.12.2017
comment
Это не идеальная ситуация: вы платите за увеличение размера b за каждое нажатие. Решение, которое я ищу, должно быть эквивалентно гибридному случаю с нулевыми накладными расходами. - person dodomorandi; 15.12.2017
comment
@dodomorandi ты прочитал последний абзац? Он говорит вам, что b будет зарезервировано заранее, и перераспределения не произойдет. - person bolov; 15.12.2017
comment
@bolov, как я уже сказал, у вас нет никакого распределения, но вы все еще манипулируете счетчиком количества объектов. Это очень небольшая цена, но в данном случае она более чем необходима. - person dodomorandi; 15.12.2017
comment
@bolov верно, я забыл об огромном количестве промахов оптимизации при использовании push. Хорошая векторизация является одним из них. Если вы мне не верите, просто измерьте это. - person dodomorandi; 16.12.2017
comment
ranges::action::push_back(v, r), когда r является диапазоном, реализуется с v.insert(v.end(), begin(r), end(r)). Это должно быть способно к векторизации, если ваша реализация STL того стоит. - person Eric Niebler; 16.12.2017

Как насчет:

ranges::transform(a, b.begin(), complexfun);

?

РЕДАКТИРОВАТЬ: ... или, может быть,

ranges::copy( a | ranges::views::transform(complexFun), begin(b) );

?

person Eric Niebler    schedule 15.12.2017
comment
Что делать, если я хочу использовать несколько представлений? Глупая вещь: преобразование a с помощью complexFun, затем добавление индекса (используя iota) к результату и сохранение в b? - person dodomorandi; 15.12.2017
comment
Хорошо, я только что получил свою концептуальную ошибку: я пытался использовать b в качестве второго аргумента ranges::copy вместо использования begin(b). Если вы хотите сказать, что это была проблема, я приму ваш ответ. Тем не менее, есть ли какой-нибудь синтаксический сахар, чтобы избежать ranges::copy и назначить ленивое представление выходному диапазону? - person dodomorandi; 15.12.2017