2015-01-28 13 views
6

के साथ अद्वितीय एल्गोरिदम std::make_move_iterator फ़ंक्शन के माध्यम से बनाए गए इटरेटर के साथ std::unique का उपयोग करने की अनुमति है? मैं the following की कोशिश की, और सफलता मिल गया:move iterators

#include <iostream> 
#include <ostream> 
#include <vector> 
#include <algorithm> 
#include <limits> 
#include <iterator> 

#include <cstdlib> 

struct A 
{ 

    A() : i(std::numeric_limits<double>::quiet_NaN()) { std::cout << __PRETTY_FUNCTION__ << "\n"; } 
    A(double ii) : i(ii) { std::cout << __PRETTY_FUNCTION__ << "\n"; } 
    A(A const & a) : i(a.i) { std::cout << __PRETTY_FUNCTION__ << "\n"; } 
    A(A && a) : i(std::move(a.i)) { std::cout << __PRETTY_FUNCTION__ << "\n"; a.i = std::numeric_limits<double>::quiet_NaN(); } 
    A & operator = (A const & a) { std::cout << __PRETTY_FUNCTION__ << "\n"; i = a.i; return *this; } 
    A & operator = (A && a) { std::cout << __PRETTY_FUNCTION__ << "\n"; i = std::move(a.i); a.i = std::numeric_limits<double>::quiet_NaN(); return *this; } 
    bool operator < (A const & a) const { std::cout << __PRETTY_FUNCTION__ << "\n"; return (i < a.i); } 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wfloat-equal" 
    bool operator == (A const & a) const { std::cout << __PRETTY_FUNCTION__ << "\n"; return (i == a.i); } 
#pragma clang diagnostic pop 

    friend 
    std::ostream & 
    operator << (std::ostream & o, A const & a) 
    { 
     return o << a.i; 
    } 

private : 

    double i; 

}; 

int 
main() 
{ 
    std::vector<A> v{1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 4.0, 4.0, 5.0, 6.0, 6.0, 7.0}; 
    std::cout << "v constructed\n\n\n\n"; 
    std::sort(v.begin(), v.end()); 
    auto const end = std::unique(std::make_move_iterator(v.begin()), std::make_move_iterator(v.end())).base(); 
    std::copy(v.begin(), end, std::ostream_iterator<A>(std::cout, " ")); 
    std::cout << std::endl; 
    return EXIT_SUCCESS; 
} 

लेकिन शायद यह कार्यान्वयन पर निर्भर सफलता है?

और <numeric> और <algorithm> से अन्य एल्गोरिदम के संबंध में क्या?

+0

'std :: अद्वितीय' वैसे भी चलता है, इसलिए मुझे नहीं लगता कि आप इससे क्या हासिल करते हैं। –

+0

@ टी.सी. आपका क्या अर्थ है? "std :: unique' copy-असाइनिंग [यहां] (http://en.cppreference.com/w/cpp/algorithm/unique) अनुभाग" संभावित कार्यान्वयन "में। – Orient

+1

यह एक अच्छा कार्यान्वयन नहीं है। असली पुस्तकालय [चाल] (http://coliru.stacked-crooked.com/a/198b772ffc2f41ba)। –

उत्तर

5

कार्यक्रम मानक द्वारा काम करने की गारंटी है।
std::unique को आगे बढ़ने की आवश्यकता है। कि इस कदम iterators दिखाने के लिए सबसे आसान तरीका है को संतुष्ट है कि आवश्यकता move_iterator की iterator_category typedef निरीक्षण करने के लिए है:

typedef typename iterator_traits<Iterator>::iterator_category iterator_category; 

आप देख सकते हैं, अंतर्निहित इटरेटर प्रकार के iterator श्रेणी सीधे अनुकूलित है। वास्तव में, इस कदम iterators का व्यवहार उनके अंतर्निहित लोगों के लगभग बराबर है, [move.iterators]/1:

कक्षा टेम्पलेट move_iterator अपने अविवेक सिवाय इसके कि अंतर्निहित इटरेटर के रूप में ही व्यवहार वाले पुनरावर्तक एडाप्टर है ऑपरेटर अंतर्निहित इटरेटर के इंडेक्शन ऑपरेटर द्वारा एक रावल्यू संदर्भ में लौटाए गए मान को स्पष्ट रूप से परिवर्तित करता है।

कोई अन्य उल्लेखनीय आवश्यकताएं हैं: जाहिर है vector<>::iterator एक इनपुट इटरेटर है (के रूप में [move.iter.requirements] के लिए आवश्यक)। केवल प्रासंगिक आवश्यकता unique से ही लगाया

*first के प्रकार MoveAssignable आवश्यकताओं (22 तालिका) संतुष्ट करेगा है।

... जो सीधे तौर पर मुलाकात की जाती है।

ध्यान दें कि चालक इटरेटर्स का उपयोग सामान्य लोगों पर कोई लाभ नहीं लेना चाहिए। आंतरिक रूप से डुप्लिकेट तत्व स्थानांतरित किए जाते हैं (इसलिए MoveAssignable आवश्यकता), इसलिए operator* से एक रावल्यू संदर्भ लौटाना आवश्यक नहीं है।

+0

नहीं, आंतरिक रूप से 'std :: अद्वितीय' को सीधे चाल असाइनमेंट का उपयोग करना चाहिए। 'स्वैप' का उपयोग करने के लिए 'MoveConstructible' भी आवश्यक होगा। –

+0

@ टी.सी. सही लगता है। क्या वास्तव में तत्वों को बदल दिया गया है, या एक स्थानांतरित राज्य में लौटे हुए नए छोर के बाद क्या हैं? – Columbo

+0

@ टी.सी. libstdC++ ऐसा लगता है कि '* ++ __ dest = _GLIBCXX_MOVE (* __ पहले) ', जो इंगित करता है कि बाद वाला सत्य है। – Columbo

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