ซึ่งสามารถทำได้ แต่ต้องใช้ขั้นตอนไม่กี่ขั้นตอนในการทำ ขั้นแรกเขียน 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
ดังนั้นคุณต้องห่อไว้ในบางสิ่งบางอย่างหรือพิจารณาการใช้