2011-08-24 12 views
6

क्या दो अलग-अलग प्रकार के सेट पर std :: set_intersection करने का कोई तरीका है?दो अलग-अलग प्रकार के सेट के लिए set_intersection

std::set<X1> l_set1; 
std::set<X2> l_set2; 

मैं जाँच करता है कि अगर X1 और X2 बराबर हैं उनके लिए कुछ तुलनित्र परिभाषित करने में सक्षम हूँ:

मैं दो सेट है।

struct sample_comparer 
{ 
    bool operator()(const &X1 p_left, const &X2 p_right) 
    { 
     return p_left == p_right; 
    } 
}; 

अब, मैं उन दो सेट पर एक सेट चौराहे करने की कोशिश:

std::set<X1> l_intersect; 
std::set_intersection(l_set1.begin(), l_set1.end(), l_set2.begin(), l_set2.end(), 
         std::inserter(l_intersect, l_intersect.begin()), sample_comparer()); 

दुर्भाग्य से, मैं इस कोड को काम करने के लिए मजबूर नहीं कर सकते हैं। मुझे यह भी यकीन नहीं है कि यह संभव है, लेकिन set_intersection के description से मुझे पता है कि मैं दो अलग-अलग पुनरावृत्तियों का उपयोग कर सकता हूं।

मैंने कुछ कोड नमूने खोजने की कोशिश की जो मैं चाहता हूं, लेकिन कोई नहीं मिला? क्या कोई मुझे मेरी समस्या के लिए एक कामकाजी कोड नमूना पेश कर सकता है?

अद्यतन: त्रुटि है:

error: stl_function.h:227: no match for 'operator<' in '__x < __y'

अग्रिम धन्यवाद!

+0

"दुर्भाग्य से, मैं इस कोड को काम करने के लिए मजबूर नहीं कर सकता।" आपको क्या कंपाइलर त्रुटियां मिलती हैं? –

+1

आपका नमूना तुलनाकर्ता सही काम नहीं करता है। तुलनात्मक तत्वों पर सख्त कमजोर आदेश लगाने से इसे कम करने की आवश्यकता है। – tokage

+0

क्या आप एक अतिभारित <ऑपरेटर 'bool ऑपरेटर <(x1, x2)' –

उत्तर

3

प्लाज़्माएचएच द्वारा टिप्पणी की समस्या समस्या है।

रास्ता set_intersection काम जैसे कार्यों है वे पहले कार्य करें: a < b और फिर b < a

एक परिणाम ample_comparer दोनों तरीकों से तुलना करने के लिए सक्षम होने की जरूरत के रूप में:

struct sample_comparer 
{ 
    bool operator()(const &X1 p_left, const &X2 p_right) 
    { 
     return p_left == p_right; 
    } 
    bool operator()(const &X2 p_left, const &X1 p_right) 
    { 
     return p_left == p_right; 
    } 
}; 

निम्नलिखित वास्तव में ऐसा नहीं करता है कुछ समझदार - लेकिन यह साफ-सुथरा संकलित करता है:

struct A 
{ 
    struct Compare { bool operator() (A const &, A const &) { return false;} }; 
}; 

struct B 
{ 
    struct Compare { bool operator() (B const &, B const &) { return false; } }; 
}; 

typedef std::set<A, A::Compare> S1; 
typedef std::set<B, B::Compare> S2; 

class IntersectionCompare 
{ 
public: 
    bool operator()(S1::value_type, S2::value_type) { return false; } 
    bool operator()(S2::value_type, S1::value_type) { return false; } 
}; 

void bar (S1 & s1, S2 & s2) 
{ 
    S1 result; 
    std::set_intersection (s1.begin() 
     , s1.end() 
     , s2.begin() 
     , s2.end() 
     , std :: insert_iterator<S1> (result, result.end()) 
     , IntersectionCompare()); 
} 
4

यह काम नहीं करेगा क्योंकि दोनों इनपुट आउटपुट इटरेटर प्रकार के लिए असाइन किए जाने योग्य हैं। आप एक्स 1, एक्स 2 में कुछ अंतर्निहित रूपांतरण ऑपरेटर जोड़ सकते हैं जो कि काम करने के लिए उनके बीच परिवर्तित हो जाते हैं।

+0

set_intersection के लिए उत्पादन रेंज सिर्फ एक से रूपांतरण की अनुमति देने की जरूरत के लिए एक तुलनित्र की जरूरत है इनपुट के (हालांकि यह निर्दिष्ट नहीं है)। Set_union या set_difference जैसे कुछ को दोनों प्रकार के रूपांतरण की आवश्यकता होती है। –

2

मुझे नहीं लगता कि यह संभव है, (कम से कम उपयोगकर्ता द्वारा परिभाषित रूपांतरण के बिना)। documentation में "प्रकारों पर आवश्यकताएं" अनुभाग से: InputIterator1 and InputIterator2 have the same value type.

+0

डॉक्स – matekm

+0

में समाधान को इंगित करने के लिए उत्तर और धन्यवाद के लिए धन्यवाद, यदि फ़ंक्शन समान होने की आवश्यकता है तो फ़ंक्शन दो अलग इनपुट इटरेटर प्रकारों की अनुमति क्यों देगा? –

0

सबसे पहले दस्तावेज़ों के अनुसार set_intersect आयन ऑपरेटर < का उपयोग कर रहा है। और दूसरा आप क्षेत्रों तुम क्या करने का उपयोग करेगा तुलना में एक तिहाई struct उस प्रकार से निकाल देंगे कर सकते हैं

std::set<X1> l_set1; 
std::set<X2> l_set2; 
struct XCompare 
{   
    int value; 
    XCompare(const X1& x) 
    { 
     value = x.value; 
    } 

    XCompare(const X2& x) 
    { 
     value = x.value; 
    } 
} 

std::set_intersection(...,...,[](const XCompare& c1, const XCompare& c2){ 
... } ) 

आप इस पथ नीचे जाने के लिए और है कि कुछ भी कर सकते एक कस्टम आवरण बना सकते हैं जब तक कि आपके दो प्रकार के कर सकते हैं

template<typename T1, typename T2> 
struct ValueWrapper 
{ 
    T1 const* v1 = nullptr; 
    T2 const* v2 = nullptr; 

    ValueWrapper(const T1& value) 
    { 
     v1 = &value; 
    } 

    ValueWrapper(const T2& value) 
    { 
     v2 = &value; 
    } 

    bool operator<(const ValueWrapper& other) 
    { 
     if (v1 != nullptr) 
     { 
      if (other.v1 != nullptr) 
      { 
       return *v1 < *(other.v2) 
      } 

... } }

template<typename T1, typename T2> 
struct ValueWrapperComparator 
{ 
    bool operator()(ValueWrapper<T1,T2> v1, ValueWrapper<T1,T2> v2) 
    { 
     return v1 < v2; 
    } 
} 

कुछ इस तरह की तुलना करें। मैंने इसका परीक्षण नहीं किया और यह संकलित नहीं होगा लेकिन आपको बिंदु मिल जाएगा।हो सकता है कि एसटीएल पुस्तकालयों में कहीं कुछ समान कुछ छिपा हुआ हो,

संपादित करें: बीटीडब्ल्यू मुझे लगता है कि आप किसी प्रकार के संस्करण प्रकार (बूस्ट :: संस्करण या std :: संस्करण) का उपयोग कर सकते हैं, मुझे लगता है कि यह पहले से ही ऐसा करता है ...

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