Bu yapılabilir, ancak temiz bir şekilde yapılması birkaç adım alır. İlk olarak, template class
bir dizi bitişik değerleri temsil eden bir yazın. Ardından , bu bitişik aralığı alan sürüme template
ne kadar büyük olduğunu bilen bir sürümü iletin .array
Impl
Son olarak, contig_range
sürümü uygulayın. Not for( int& x: range )
için çalışan contig_range
ben hayata çünkü begin()
ve end()
ve işaretçileri yineleyiciler bulunmaktadır.
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 );
}
(test edilmemiştir, ancak tasarım çalışmalıdır).
Ardından .cpp
dosyanızda:
void mulArrayImpl(contig_range<int> rng, const int multiplier) {
for(auto& e : rng) {
e *= multiplier;
}
}
Bunun dezavantajı, dizinin içeriği üzerinde döngü yapan kodun dizinin ne kadar büyük olduğunu (derleme zamanında) bilmemesidir, bu da optimizasyona mal olabilir. Uygulamanın başlıkta olması gerekmemesi avantajına sahiptir.
A'yı açıkça oluştururken dikkatli olun contig_range
, sanki onu iletirseniz, verilerin bitişik set
olduğunu varsayar set
, bu yanlıştır ve her yerde tanımsız davranışlar sergiler. Bunun std
üzerinde çalışacağı garanti edilen tek iki kap vector
ve array
(ve olduğu gibi C-tarzı diziler!). deque
rasgele erişim olmasına rağmen (tehlikeli olarak, küçük parçalar halinde bitişiktir!), list
hatta yakın değildir ve ilişkilendirici (sıralı ve sırasız) kapsayıcılar eşit derecede bitişik değildir.
Üç kurucular Yani nerede uygulanan std::array
, std::vector
temelde üsleri kapsayan ve C tarzı diziler.
Uygulama []
hem kolaydır ve aralarında for()
ve []
bir istediğiniz bu çoğu ise array
, değil mi için?
std::vector
.