これは可能ですが、きれいに行うにはいくつかの手順が必要です。まず、template class
連続する値の範囲を表すaを記述します。次に、この連続する範囲をとるバージョンに、template
どれほど大きいかを知っているバージョンを転送します。array
Impl
最後に、contig_range
バージョンを実装します。注for( int& x: range )
のために働くcontig_range
私が実装するので、begin()
およびend()
とポインタはイテレータです。
template<typename T>
struct contig_range {
T* _begin, _end;
contig_range( T* b, T* e ):_begin(b), _end(e) {}
T const* begin() const { return _begin; }
T const* end() const { return _end; }
T* begin() { return _begin; }
T* end() { return _end; }
contig_range( contig_range const& ) = default;
contig_range( contig_range && ) = default;
contig_range():_begin(nullptr), _end(nullptr) {}
// maybe block `operator=`? contig_range follows reference semantics
// and there really isn't a run time safe `operator=` for reference semantics on
// a range when the RHS is of unknown width...
// I guess I could make it follow pointer semantics and rebase? Dunno
// this being tricky, I am tempted to =delete operator=
template<typename T, std::size_t N>
contig_range( std::array<T, N>& arr ): _begin(&*std::begin(arr)), _end(&*std::end(arr)) {}
template<typename T, std::size_t N>
contig_range( T(&arr)[N] ): _begin(&*std::begin(arr)), _end(&*std::end(arr)) {}
template<typename T, typename A>
contig_range( std::vector<T, A>& arr ): _begin(&*std::begin(arr)), _end(&*std::end(arr)) {}
};
void mulArrayImpl( contig_range<int> arr, const int multiplier );
template<std::size_t N>
void mulArray( std::array<int, N>& arr, const int multiplier ) {
mulArrayImpl( contig_range<int>(arr), multiplier );
}
(テストされていませんが、設計は機能するはずです)。
次に、.cpp
ファイルで:
void mulArrayImpl(contig_range<int> rng, const int multiplier) {
for(auto& e : rng) {
e *= multiplier;
}
}
これには、配列の内容をループするコードが配列の大きさ(コンパイル時に)を知らないため、最適化にコストがかかるという欠点があります。これは、実装がヘッダーにある必要がないという利点があります。
を明示的に作成するcontig_range
場合は注意してください。これを渡すとset
、set
データが連続していると見なされ、偽であり、どこでも未定義の動作を行うためです。std
これが機能することが保証されている唯一の2つのコンテナーはvector
、and array
(およびCスタイルの配列です)。 deque
ランダムアクセスであるにもかかわらず、隣接していない(危険なことに、小さなチャンクで連続している!)か、list
近接しておらず、連想(順序付けと順序付けなし)コンテナーも同様に隣接していません。
したがって、私が実装した3つのコンストラクタwhere std::array
、std::vector
および基本的にベースをカバーするCスタイルの配列。
実装は[]
、同様に簡単である、との間for()
と[]
、あなたは何をしたいのほとんどであるarray
ため、それはないですか?
std::vector
ます。