Ini bisa dilakukan, tetapi perlu beberapa langkah untuk melakukannya dengan rapi. Pertama, tulis a template class
yang mewakili rentang nilai yang berdekatan. Kemudian teruskan template
versi yang mengetahui seberapa besar array
is ke Impl
versi yang mengambil rentang yang berdekatan ini.
Terakhir, terapkan contig_range
versinya. Perhatikan itu for( int& x: range )
berfungsi untuk contig_range
, karena saya menerapkan begin()
dan end()
dan penunjuk adalah iterator.
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) {}
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 );
}
(tidak diuji, tetapi desain harus berfungsi).
Kemudian, di .cpp
file Anda :
void mulArrayImpl(contig_range<int> rng, const int multiplier) {
for(auto& e : rng) {
e *= multiplier;
}
}
Ini memiliki kelemahan bahwa kode yang mengulang konten array tidak tahu (pada waktu kompilasi) seberapa besar array itu, yang dapat memerlukan biaya pengoptimalan. Keuntungannya adalah implementasinya tidak harus di header.
Berhati-hatilah saat membuat a secara eksplisit contig_range
, karena jika Anda meneruskannya, set
itu akan menganggap bahwa set
datanya bersebelahan, yang salah, dan melakukan perilaku tidak terdefinisi di semua tempat. Hanya dua std
container yang dijamin akan berfungsi adalah vector
dan array
(dan array C-style, saat terjadi!). deque
meskipun akses acak tidak bersebelahan (berbahaya, itu bersebelahan dalam potongan kecil!), list
bahkan tidak dekat, dan wadah asosiatif (teratur dan tidak berurutan) sama-sama tidak bersebelahan.
Jadi tiga konstruktor yang saya implementasikan di mana std::array
, std::vector
dan array gaya-C, yang pada dasarnya mencakup pangkalan.
Menerapkannya []
juga mudah, dan di antara for()
dan []
itulah yang paling Anda inginkan array
, bukan?
std::vector
.