2016-08-12 6 views
7

में कॉन्स्ट तर्क तर्क मैं जोड़े की सूची से तत्वों को निकालने जा रहा हूं। जब मैंstd :: remove_if

std::pair<const int, bool>

मैं निम्नलिखित संकलन त्रुटि मिलती है की तरह एक जोड़ी का उपयोग कर रहा: (

int main() 
{ 
    int id = 2; 

    std::list< std::pair <const int, bool> > l; 
    l.push_back(std::make_pair(3,true)); 
    l.push_back(std::make_pair(2,false)); 
    l.push_back(std::make_pair(1,true)); 

    l.erase(std::remove_if(l.begin(), l.end(), 
     [id](std::pair<const int, bool>& e) -> bool { 
     return e.first == id; })); 

    for (auto i: l) { 
     std::cout << i.first << " " << i.second << std::endl; 
    } 
} 

मैं जानता हूँ कि सही करें:

In file included from /usr/local/include/c++/6.1.0/utility:70:0,

from /usr/local/include/c++/6.1.0/algorithm:60,

from main.cpp:1:

/usr/local/include/c++/6.1.0/bits/stl_pair.h: In instantiation of 'std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_T1, _T2>&&) [with _T1 = const int; _T2 = bool]':

/usr/local/include/c++/6.1.0/bits/stl_algo.h:868:16: required from '_ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = std::_List_iterator > _Predicate = __gnu_cxx::__ops::_Iter_pred&)> >]'

/usr/local/include/c++/6.1.0/bits/stl_algo.h:936:30: required from '_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = std::_List_iterator > _Predicate = main()::&)>]'

main.cpp:17:32: required from here

/usr/local/include/c++/6.1.0/bits/stl_pair.h:319:8: error: assignment of read-only member 'std::pair::first'

first = std::forward(__p.first);

यह नमूना कोड है अगर मैं गलत हूं):

  1. मुझे वही समस्या होगी जब तक सूची के किसी भी तत्व में स्थिरता हो, उदाहरण के लिए, list <const int> एक संकलन त्रुटि भी लौटाएगा।

  2. यदि मैं जोड़ी के पहले तत्व में कॉन्स्ट को हटा देता हूं तो कोड काम करेगा।

    l.remove_if([id](std::pair<const int, bool>& e) -> bool { 
        return e.first == id; }); 
    

लेकिन मेरे सवाल है, वास्तव में एसटीडी की अंदरूनी कामकाज क्या हैं :::

  • अधिक सुरुचिपूर्ण और कारगर तरीका यह remove_if सूची पद्धति का उपयोग करके, इस तरह से है करने के लिए remove_if जो कंटेनर के तत्वों को लागू करता है const नहीं?

  • +0

    'std :: remove_if' को डिफरेंस किए गए प्रकार की आवश्यकता है * MoveAssignable *, जो' std :: pair 'नहीं है। – user657267

    उत्तर

    4

    आप std::remove_if के प्रकार और इटरेटर आवश्यकताओं को देखें, तो आप देख सकते हैं कि कार्यान्वयन (ऊपर के लिंक से) निम्न के समान होनी चाहिए:

    template<class ForwardIt, class UnaryPredicate> 
    ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p) 
    { 
        first = std::find_if(first, last, p); 
        if (first != last) 
         for(ForwardIt i = first; ++i != last;) 
          if (!p(*i)) 
           *first++ = std::move(*i); 
        return first; 
    } 
    

    Ie, एल्गोरिथ्म केवल कि मान लिया गया है इटरेटर्स के पास आगे की क्षमताएं होती हैं, और तत्व चलने योग्य होते हैं, और यह move के आसपास के तत्व होते हैं। बेशक, एस const ऑब्जेक्ट्स पर नहीं किया जा सकता है।

    5

    सामान्य std::remove_if शफ़ल आइटम मूल्यों के आसपास (यह आम तौर पर सदस्य समारोह erase के साथ संयोजन में उपयोग किया जाता है वास्तव में तार्किक मिट मूल्यों हटाने के लिए) अनुक्रम के अंत में तार्किक मिट मूल्यों डाल करने के लिए। जब कोई आइटम कॉपी करने योग्य या जंगम नहीं होता है तो यह शफल नहीं कर सकता है। इसके बजाय std::list::remove_if का उपयोग करें।

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