रैंडम एक्सेस iterators साथ
, और संकलन समय पर एक निश्चित आकार के बावजूद आपको ऐसा करने की एक pack of indices उपयोग कर सकते हैं:
template <std::size_t... Indices>
struct indices {
using next = indices<Indices..., sizeof...(Indices)>;
};
template <std::size_t N>
struct build_indices {
using type = typename build_indices<N-1>::type::next;
};
template <>
struct build_indices<0> {
using type = indices<>;
};
template <std::size_t N>
using BuildIndices = typename build_indices<N>::type;
template <typename Iterator>
using ValueType = typename std::iterator_traits<Iterator>::value_type;
// internal overload with indices tag
template <std::size_t... I, typename RandomAccessIterator,
typename Array = std::array<ValueType<RandomAccessIterator>, sizeof...(I)>>
Array make_array(RandomAccessIterator first, indices<I...>) {
return Array { { first[I]... } };
}
// externally visible interface
template <std::size_t N, typename RandomAccessIterator>
std::array<ValueType<RandomAccessIterator>, N>
make_array(RandomAccessIterator first, RandomAccessIterator last) {
// last is not relevant if we're assuming the size is N
// I'll assert it is correct anyway
assert(last - first == N);
return make_array(first, BuildIndices<N> {});
}
// usage
auto a = make_array<N>(v.begin(), v.end());
यह एक संकलक मध्यवर्ती प्रतियां eliding करने में सक्षम हो जाती है। मुझे लगता है कि धारणा एक बड़ा खिंचाव नहीं है।
असल में, यह इनपुट इटरेटर के साथ भी किया जा सकता है, क्योंकि ब्रेसिड-इनिट-सूची में प्रत्येक तत्व की गणना अगले तत्व (§8.5.4/4) की गणना से पहले अनुक्रमित होती है।
// internal overload with indices tag
template <std::size_t... I, typename InputIterator,
typename Array = std::array<ValueType<InputIterator>, sizeof...(I)>>
Array make_array(InputIterator first, indices<I...>) {
return Array { { (void(I), *first++)... } };
}
*first++
चूंकि यह किसी भी I
, हम एक डमी I
जरूरत पैक विस्तार भड़काने के लिए नहीं है। void()
के साथ प्रभाव की कमी के बारे में चेतावनियों को शांत करने और अधिभारित कॉमा को रोकने के लिए बचाव के लिए कॉमा ऑपरेटर।
स्रोत
2012-06-07 10:33:27
क्या वरीयता के लिए कोई कारण है? प्रदर्शन लगभग ठीक वही होगा क्योंकि डिफ़ॉल्ट कन्स्ट्रक्टर (आमतौर पर) केवल वही संरचना संरचना आवंटित करता है जो आपको वैसे भी चाहिए। कोई अतिरिक्त आवंटन, प्रतिलिपि या मुक्त नहीं होगा। –
@ डेविडस्वार्टज़: शायद मेरे पास मेरी कक्षा में एक कॉन्स सरणी सदस्य है और इसलिए मुझे इसे निर्माता निकाय की बजाय प्रारंभकर्ता सूची में प्रारंभ करना होगा? – HighCommander4
--- क्या हम खुद को यादृच्छिक एक्सेस इटरेटर्स तक सीमित कर सकते हैं? यदि हां, तो मेरे पास कुछ प्रकार का समाधान है --- कभी नहीं, संकलन समय पर * आकार * प्राप्त करने का कोई तरीका नहीं है। –