Несомненно. Написал это:
template<int> struct seq {};
template<typename seq> struct seq_len;
template<template<int...>class seq,int s0,int...s>
struct seq_len<seq<s0,s...>>:std::integral_constant<std::size_t,seq_len<seq<s...>>::value> {};
template<template<int...>class seq,>
struct seq_len<seq<>:std::integral_constant<std::size_t,0> {};
template<int Min, int Max, int... s>
struct make_seq: make_seq<Min, Max-1, Max-1, s...> {};
template<int Min, int... s>
struct make_seq<Min, Min, s...> {
typedef seq<s...> type;
};
template<int Max, int Min=0>
using MakeSeq = typename make_seq<Min,Max>::type;
template<std::size_t src, typename T, int... indexes>
std::array<T, sizeof...(indexes)> get_elements(seq<indexes...>, std::array<T, src > const& inp) {
return { inp[indexes]... };
}
template<int len, std::size_t src, typename T>
auto first_elements(std::array<T, src > const& inp)
-> decltype(get_elements(inp, MakeSeq<len>())
{
return get_elements(inp, MakeSeq<len>());
}
Если во время компиляции indexes...
делает переназначение и MakeSeq делает SEQ от 0 до N-1.
Это поддерживает как произвольный набор индексов (через get_elements
), так и первый n (через first_elements
).
Использование:
std::array< int, 10 > arr = {0,1,2,3,4,5,6,7,8,9};
std::array< int, 6 > slice = get_elements(arr, seq<2,0,7,3,1,0>());
std::array< int, 5 > start = first_elements<5>(arr);
, который избегает всех петель, либо явных или неявных.
Пара итераторов - это самый близкий C++ к фрагменту. Что-то вроде Boost.Range также позволяет упаковать их вместе в один объект, подобный срезу. –