Это можно сделать, но чтобы все было чисто, нужно выполнить несколько шагов. Во-первых, напишите a template class, представляющий диапазон смежных значений. Затем перенаправьте 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) {}
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;
}
}
У этого есть обратная сторона: код, который перебирает содержимое массива, не знает (во время компиляции), насколько велик массив, что может привести к оптимизации затрат. Его преимущество в том, что реализация не обязательно должна быть в заголовке.
Будьте осторожны при явном построении a contig_range, так как если вы передадите его, setон будет предполагать, что setданные являются смежными, что является ложным, и повсюду будет вести себя неопределенно. Единственные два stdконтейнера, с которыми это гарантированно будет работать, - это vectorи array(и массивы в стиле C, как это бывает!). dequeнесмотря на то, что произвольный доступ не является непрерывным (что опасно, он непрерывен небольшими порциями!), listдаже не близок, а ассоциативные (упорядоченные и неупорядоченные) контейнеры одинаково не смежны.
Итак, три конструктора, которые я реализовал std::array, std::vectorи массивы в стиле C, которые в основном покрывают основы.
Реализация []легко , как хорошо, так и между for()и []что большая часть того, что вы хотите, arrayибо, не так ли?
std::vector.