2012-11-23 23 views
12

मैं एक वेक्टर फ़िल्टर करने की कोशिश कर रहा हूं ताकि इसमें केवल एक विशिष्ट मान हो।क्या आप भविष्यवाणी के लिए अतिरिक्त पैरामीटर पास कर सकते हैं?

उदा सुनिश्चित करें कि वेक्टर में केवल "abc" मान के तत्व शामिल हैं।

अभी, मैं इसे remove_copy_if के साथ प्राप्त करने की कोशिश कर रहा हूं।

क्या स्टडी के एल्गोरिदम में से किसी एक का उपयोग करते समय भविष्यवाणी के लिए अतिरिक्त पैरामीटर पास करने का कोई तरीका है?

std::vector<std::string> first, second; 
first.push_back("abc"); 
first.push_back("abc"); 
first.push_back("def"); 
first.push_back("abd"); 
first.push_back("cde"); 
first.push_back("def"); 

std::remove_copy_if(first.begin(), first.end(), second.begin(), is_invalid); 

मैं एक विधेय के रूप में निम्नलिखित समारोह पारित करने के लिए उम्मीद कर रहा हूँ, लेकिन यह अधिक संभावना है कि यह सिर्फ वर्तमान मूल्य remove_copy_if और अगले द्वारा जांच की जा रही की तुलना हो जाएंगे लगता है।

bool is_invalid(const std::string &str, const std::string &wanted) 
{ 
    return str.compare(wanted) != 0; 
} 

मुझे एहसास है कि मैं शायद इस गलत तरीके से आ रहा हूं इसलिए किसी भी सुझाव की सराहना की जाएगी!

धन्यवाद

+0

बस सोच रहा है - आप केवल वही तत्वों के साथ वेक्टर का उपयोग कैसे करते हैं? – Zane

+0

मैंने अपना उदाहरण जितना संभव हो उतना सरल बनाने की कोशिश की ताकि यह समझ में आया :) मैंने इसके साथ क्या किया था एक वेक्टर से तत्वों को निकालना जो एक निश्चित पैटर्न (रेगेक्स के साथ) फिट बैठता था। – noko

उत्तर

16

साथ उदाहरण के बजाय एक functor निर्धारित करें:

struct is_invalid 
{ 
    is_invalid(const std::string& a_wanted) : wanted(a_wanted) {} 
    std::string wanted; 
    bool operator()(const std::string& str) 
    { 
     return str.compare(wanted) != 0; 
    } 
}; 

std::remove_copy_if(first.begin(), 
        first.end(), 
        second.begin(), 
        is_invalid("abc")); 

या यदि सी ++ 11 उपयोग एक लैम्ब्डा:

std::string wanted("abc"); 
std::remove_copy_if(first.begin(), first.end(), second.begin(), 
    [&wanted](const std::string& str) 
    { 
     return str.compare(wanted) != 0; 
    }); 

ध्यान दें कि उत्पादन वेक्टर, second, remove_copy_if() को कॉल करने से पहले तत्व होना चाहिए:

// Create 'second' after population of 'first'. 
// 
std::vector<std::string> second(first.size()); 

std::string wanted = "abc"; 
int copied_items = 0; 
std::remove_copy_if(first.begin(), first.end(), second.begin(), 
    [&wanted, &copied_items](const std::string& str) -> bool 
    { 
     if (str.compare(wanted) != 0) return true; 
     copied_items++; 
     return false; 
    }); 
second.resize(copied_items); 

के रूप में functor विधेय कॉपी कर रहे हैं और अधिक प्रयास copied_items जानकारी बनाए रखने के लिए आवश्यक है। सुझाए गए समाधानों के लिए Pass std algos predicates by reference in C++ देखें।

+0

मुझे इस समाधान का उपयोग करने का प्रयास करते समय, "अपरिभाषित संदर्भ" के बारे में कोई त्रुटि मिलती है, क्या हो रहा है पर कोई विचार है? – noko

+0

@ नोको, क्या आप कोड को वैचारिक या समान में पोस्ट कर सकते हैं? ध्यान दें कि आपको कंपाइलर को C++ 11 लैम्बडास का समर्थन करना होगा (g ++ में आपको '-std = C++ 0x' कंपाइलर स्विच का उपयोग करने की आवश्यकता है)। – hmjd

+0

कभी भी ध्यान न दें, मैं फ़ंक्शन से पहले क्लासनाम :: जोड़ना भूल गया :( – noko

8

मेक functor, या std/boost::bind का उपयोग करें।

struct is_invalid 
{ 
public: 
    is_invalid(const std::string& w):wanted(w) { } 
    bool operator() (const std::string& str) 
    { 
     return str.compare(wanted) != 0; 
    } 
private: 
    std::string wanted; 
}; 

std::remove_copy_if(first.begin(), first.end(), second.begin(), is_invalid("abc")); 

बाँध

bool is_invalid(const std::string &str, const std::string &wanted) 
{ 
    return str.compare(wanted) != 0; 
} 

std::remove_copy_if(first.begin(), first.end(), second.begin(), 
boost::bind(is_invalid, _1, "abc")); 
संबंधित मुद्दे