2013-06-23 34 views
7

Tôi có một lớp mẫu được định nghĩa như thế nàyđiều hành quá tải bên ngoài một lớp mẫu với chuyển đổi tiềm ẩn

template<class T> class Wrap 
{ 
    /* ... */ 
public: 
    Wrap(const T&); 
    /* other implicit conversions */ 

    /* ... */ 
}; 

Tôi muốn xác định tất cả các toán tử so sánh cho lớp này bên ngoài lớp học như thế này

template<typename T> bool operator == (const Wrap<T>&, const Wrap<T>&) 
{ 
    // Do comparison here 
} 

Tuy nhiên, tuyên bố này không hỗ trợ chuyển đổi tiềm ẩn của const T& hoặc bất kỳ loại nào khác, thành const Wrap<T>&.

Vì vậy, câu hỏi của tôi là làm thế nào để làm cho nó hỗ trợ chuyển đổi tiềm ẩn khi một trong các toán hạng là loại Wrap<T> và khác không phải là. Tôi không muốn viết nhiều khai báo của mỗi toán tử cho mỗi hoán vị có thể.

Trả lời

4
template<class T> struct is_wrap : std::false_type {}; 
template<class T> struct is_wrap<Wrap<T>> : std::true_type {}; 

template<class T1, class T2> typename std::enable_if<is_wrap<typename std::common_type<T1, T2>::type>::value, bool>::type operator == (const T1& t1, const T2& t2) 
{ 
    const typename std::common_type<T1, T2>::type& tc1 = t1, tc2 = t2; 
    // compare with tc1 and tc2 
} 
+0

Câu trả lời hay. Tôi đoán u bị mất tham chiếu cho 'tc2' mặc dù. – user1353535

1

Một người nào khác sẽ nói rõ điều này hơn, nhưng tôi nghĩ vấn đề là trình biên dịch không thể suy ra T trong Wrap<T> mà không chuyển cho đối tượng Wrap. Tôi nghĩ rằng tình huống của bạn nên được giải quyết nếu bạn đưa ra một đối số mẫu operator== một cách rõ ràng: operator==<int>(7, 4), ví dụ như sẽ hoạt động.

Tôi không có một trình biên dịch trước mặt tôi, nhưng đây là cố gắng của tôi:

template<typename T> 
typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const Wrap<T>& l, const T& r) 
{ 
    return l.stuff == Wrap<T>(r).stuff; 
} 

template<typename T> 
typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const T& l, const Wrap<T>& r) 
{ 
    return r == l; // call above operator 
} 

này nên hoạt động nếu một trong hai bên là một Wrap và phía bên kia thì không. Bạn cũng có thể làm cả hai bên như const T&, tuy nhiên nếu thực sự Wrap ngầm constructible từ bất kỳ T bạn sẽ gió lên bằng operator== của bạn đối với nhiều người so sánh ngoài ý muốn, thậm chí của int s, string s, vv

+0

này vẫn đòi hỏi tôi để thêm 2 tờ khai khác cho mỗi nhà điều hành mà tôi muốn tránh. – user1353535

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