Есть вот такая конструкция изображающая range в стиле Alexandrescu (у него немного по другому но принцип тот же).
slice — фрагмент последовательности:
template <typename T >
struct slice
{
const T* start;
uint length;
slice(): start(0), length(0) {}
slice(const slice& src): start(src.start), length(src.length) {}
slice(const T* start_, uint length_) { start = start_; length = length_; }
slice(const T* start_, const T* end_): start(start_), length(end_>=start_?uint(end_-start_):0) {}
slice& operator = (const slice& src) { start = src.start; length = src.length; return *this; }
const T& operator[] ( uint idx ) const
{
if(idx < length)
return start[idx];
assert(false);
return black_hole();
}
...
}
и есть набор методов и алгоритмов вокруг этого. Типа slice.accumulate(T init) и пр. Все в общем-то хорошо.
Но вот требуется механизм который я называю unzip (как обратный
zip'у):
Скажем есть структура
struct foo {
int vmin;
int vmax;
int val;
};
и slice от массива оных:
slice<foo> sequence;
и задача: посчитать сумму всех полей vmax в последовательности.
Пока получается как-то так:
int vmax_total = sequence.unzip([](const foo& el){return el.vmax}).accumulate(0);
(unzip порождает вторичный slice c функцией аксессором — фактически последовательность int в данном случае).
Но как-то это все неэстечично выглядит — не сильно лучше чем решение "в лоб":
int vmax_total = 0;
for( int n = 0; n < foo.length; ++n )
vmax_total += sequence[n].vmax;
Возможно ли какое-нибудь достойное решение с использованием C++11 ?