2011-08-24 21 views
6

Có cách nào để làm std :: set_intersection trên hai loại khác nhau của bộ?set_intersection cho hai loại khác nhau của bộ

tôi có hai bộ:

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

Tôi có thể xác định một số so sánh cho họ để kiểm tra nếu X1 và X2 đều bình đẳng.

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

Bây giờ, tôi cố gắng làm một ngã tư thiết lập trên những hai bộ:

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()); 

Thật không may, tôi không thể ép buộc mã này để làm việc. Tôi thậm chí không chắc chắn nếu điều này là có thể, nhưng từ description của set_intersection tôi biết rằng tôi có thể sử dụng hai trình lặp khác nhau.

Tôi đã cố gắng tìm kiếm một số mẫu mã thực hiện những gì tôi muốn nhưng không tìm thấy bất kỳ mẫu nào? Ai đó có thể trình bày cho tôi một mẫu mã làm việc cho vấn đề của tôi?

Cập nhật: lỗi là:

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

Cảm ơn trước!

+0

"Rất tiếc, tôi không thể buộc mã này hoạt động". Lỗi trình biên dịch nào bạn nhận được? –

+1

Trình so sánh mẫu của bạn không làm điều đúng. Nó cần phải là một ít hơn, áp đặt một thứ tự yếu nghiêm ngặt trên các yếu tố so sánh. – tokage

+0

Bạn đã thử cung cấp một toán tử

Trả lời

3

Nhận xét của PlasmaHH có thể là vấn đề.

Cách các chức năng như công việc set_intersection là lần đầu tiên họ làm: a < b và sau đó b < a

Kết quả là ample_comparer cần để có thể so sánh cả hai cách:

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; 
    } 
}; 

Sau đây không thực sự làm bất kỳ điều gì hợp lý - nhưng nó biên dịch rõ ràng:

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

Nó sẽ không hoạt động vì cả hai đầu vào phải được gán cho loại trình vòng lặp đầu ra. Bạn có thể thêm một số toán tử chuyển đổi ngầm vào X1, X2 để chuyển đổi giữa chúng để làm việc đó.

+0

Đối với set_intersection phạm vi đầu ra chỉ cần cho phép chuyển đổi từ một của các đầu vào (mặc dù nó không được chỉ định cái nào). Một cái gì đó như set_union hoặc set_difference yêu cầu chuyển đổi từ cả hai loại. –

2

Tôi không nghĩ điều đó là có thể, (ít nhất là không có chuyển đổi do người dùng xác định). Từ phần "Yêu cầu về loại" trong documentation: InputIterator1 and InputIterator2 have the same value type.

+0

Cảm ơn bạn đã trả lời và cảm ơn bạn đã chỉ ra giải pháp trong tài liệu – matekm

+0

Tại sao chức năng cho phép hai loại trình lặp đầu vào khác nhau nếu giá trị cần phải giống hệt nhau? –

0

Trước hết theo các tài liệu set_intersect ion đang sử dụng toán tử <. Và thứ hai bạn có thể làm cho một cấu trúc thứ ba cho phép trích xuất từ ​​loại các trường bạn sẽ sử dụng để làm so sánh

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){ 
... } ) 

Bạn có thể đi xuống con đường này và tạo một wrapper tùy chỉnh mà có thể làm bất cứ điều gì trừ khi hai loại của bạn có thể so sánh

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; 
    } 
} 

Something như thế. Tôi đã không kiểm tra nó và nó sẽ không biên dịch nhưng bạn nhận được điểm.Có lẽ một cái gì đó tương tự là ẩn một cái gì đó tương tự ở một nơi nào đó trong các thư viện STL

Edit: Btw tôi nghĩ rằng bạn có thể sử dụng một số loại biến thể (tăng :: biến thể hoặc std :: biến thể) Tôi nghĩ rằng nó đã ...

Các vấn đề liên quan