C++ で配列のスライスを取得する簡単な方法はありますか?
つまり、私は持っています
array<double, 10> arr10;
の最初の 5 つの要素で構成される配列を取得したいarr10
:
array<double, 5> arr5 = arr10.???
(最初の配列を反復してデータを入力する以外)
のコンストラクターstd::array
は暗黙的に定義されているため、別のコンテナーまたはイテレーターの範囲で初期化することはできません。最も近い方法は、構築中にコピーを処理するヘルパー関数を作成することです。これにより、あなたが達成しようとしていると私が信じている単一フェーズの初期化が可能になります。
template<class X, class Y>
X CopyArray(const Y& src, const size_t size)
{
X dst;
std::copy(src.begin(), src.begin() + size, dst.begin());
return dst;
}
std::array<int, 5> arr5 = CopyArray<decltype(arr5)>(arr10, 5);
std::copy
コピーを自分で使用したり、反復処理したりすることもできます。
std::copy(arr10.begin(), arr10.begin() + 5, arr5.begin());
もちろん。これを書いた:
template<int...> struct seq {};
template<typename seq> struct seq_len;
template<int s0,int...s>
struct seq_len<seq<s0,s...>>:
std::integral_constant<std::size_t,seq_len<seq<s...>>::value> {};
template<>
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, typename T, std::size_t src>
auto first_elements( std::array<T, src > const& inp )
-> decltype( get_elements( MakeSeq<len>{}, inp ) )
{
return get_elements( MakeSeq<len>{}, inp );
}
コンパイル時indexes...
に再マッピングが行われ、MakeSeq は 0 から n-1 までの seq を作成します。
実例。
これは、インデックスの任意のセット ( 経由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);
これにより、明示的または暗黙的なすべてのループが回避されます。