2015-12-21 11 views
17

में लिखते हैं "इटरेटर" के लिए सामान्य कार्यों लेखन पर्वतमाला मैं आमतौर पर करते हैं:अनुमान प्रकार सी ++

template <typename Iter> auto func(Iter &first, Iter &last) 
{ 
    using IterType = typename std::iterator_traits<Iter>::value_type; 
    ... 
} 

और फिर भी एक तिहाई:

template <typename Iter> auto func(Iter &first, Iter &last) 
{ 
    using IterType = typename std::decay<decltype(*first)>::type; 
    ... 
} 

एक और तरीका हो रहा है

template <typename Iter> auto func(Iter &first, Iter &last) 
{ 
    using IterType = typename Iter::value_type; 
    ... 
} 

iterator_traits लागू किए बिना।

सिद्धांत रूप में, मेरे कार्यों को केवल first और last के रूप में हीटरेटर प्राप्त करना चाहिए और दूसरा फॉर्म आदर्श रूप से (imho) प्रकार प्राप्त करने के लिए सबसे बेवकूफ तरीका होगा। लेकिन typename std::decay<decltype(*first)>::typeIter परपरिभाषित करने के लिए प्रतिबंध लगाने के लिए सबसे सामान्य मुहावरे का उपयोग कर रहा है?

+6

मुझे लगता है कि यह मूल्य से इटरेटर को पास करने के लिए मूर्खतापूर्ण है। – Lingxi

+4

यदि 'iterator_traits' कुछ के लिए काम नहीं करता है, तो कहा गया है कि कुछ इटेटरेटर नहीं है। –

उत्तर

22

दूसरा सबसे बेवकूफ है।

  • पहले प्रॉक्सी (std :: वेक्टर < bool>)
  • तीसरे के साथ काम नहीं करता है संकेत के साथ काम नहीं करता।
10

इनमें से कोई भी मूर्खतापूर्ण नहीं है; आपको संदर्भ के अनुसार नहीं, मूल्य से iterators गुजरना चाहिए। यहाँ जीसीसी 4.9 में for_each के लिए हस्ताक्षर है:

template<typename _InputIterator, typename _Function> 
_Function 
for_each(_InputIterator __first, _InputIterator __last, _Function __f) 

आप देख सकते हैं, यह मूल्य द्वारा पारित किया है। आपका कार्यों मुहावरेदार उपयोग में काम नहीं करेगा:

func(v.begin(), v.end()); // error, binding non-const ref to rvalue! 

इसके अलावा, iterator_traits से गुजर रही बस मुहावरेदार से अधिक है, यह मूल रूप से आवश्यक है। जैसा कि एसटीएल के संबंध में है, इस तरह के टाइपपीफ को पूरी तरह से iterator_traits के माध्यम से परिभाषित किया जाता है: http://en.cppreference.com/w/cpp/concept/ForwardIterator। iterator_traits जेनेरिक मामले के लिए उचित डिफ़ॉल्ट प्रदान करता है, लेकिन यह अलग-अलग चीजों को करने के लिए विशिष्ट (जैसे पॉइंटर्स के लिए) हो सकता है। Iterator_traits के माध्यम से नहीं जा रहा है मूल रूप से इसका मतलब है कि कोई एक अनुपालन इटरेटर लिख सकता है जो एसटीएल के साथ काम करता है लेकिन आपका कोड नहीं।

संबंधित मुद्दे