यह किया जा सकता है, लेकिन इसे साफ करने के लिए कुछ कदम उठाए जाते हैं। सबसे पहले, एक लिखें जो template classसन्निहित मूल्यों की एक श्रृंखला का प्रतिनिधित्व करता है। फिर एक templateसंस्करण को आगे बढ़ाएं जो जानता arrayहै Implकि इस सन्निहित सीमा को लेने वाले संस्करण के लिए कितना बड़ा है ।
अंत में, contig_rangeसंस्करण को लागू करें । ध्यान दें कि for( int& x: range )के लिए काम करता contig_rangeहै, क्योंकि मैं लागू किया begin()और end()और संकेत iterators हैं।
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कंटेनरों कि यह काम करने की गारंटी है vectorऔर array(और सी-स्टाइल सरणियों, जैसा कि ऐसा होता है!)। dequeयादृच्छिक अभिगम होने के बावजूद यह खतरनाक नहीं है (खतरनाक रूप से, यह छोटे टुकड़ों में सन्निहित है!), listकरीब भी नहीं है, और साहचर्य (आदेशित और अव्यवस्थित) कंटेनर समान रूप से गैर-संक्रामक हैं।
इसलिए जिन तीन कंस्ट्रक्टरों को मैंने लागू किया है std::array, वे हैं, std::vectorऔर सी-स्टाइल सरणियाँ, जो मूल रूप से आधारों को कवर करती हैं।
लागू []करना आसान है, और बीच में है for()और []जो आप के लिए सबसे ज्यादा चाहते हैं array, है ना?
std::vector।