Tôi đang gặp sự cố với thư viện chuẩn C++. Ví dụ sau không biên dịch: (lưu ý điều này được cắt giảm để tạo ra một ví dụ tối thiểu do đó không có ý nghĩa nhiều như nó)Làm cách nào để chỉ định toán tử đã quá tải trong một không gian tên khác?
#include <algorithm>
#include <string>
#include <vector>
namespace otherns {
class Property {
public:
const std::string &getName() const { return m_name; }
private:
std::string m_name;
};
}
bool operator==(const otherns::Property &a, const otherns::Property &b) {
return a.getName() == b.getName();
}
/* Merge, second takes priority */
std::vector<otherns::Property>
merge_props(const std::vector<otherns::Property> &xs,
const std::vector<otherns::Property> &ys) {
std::vector<otherns::Property> ans = ys;
for (const auto &x : xs) {
if (std::find(ans.begin(), ans.end(), x) == ans.end()) {
ans.push_back(x);
}
}
return ans;
}
Lỗi này là "nhị phân '==': không tìm thấy toán tử nào một toán hạng bên trái của loại 'otherns :: Property' (hoặc không có chuyển đổi chấp nhận được) "xảy ra ở đâu đó trong việc thực hiện std::find
. Điều này là với MSVC nhưng tôi cũng đã thử với clang và gcc, với một kết quả tương tự.
Các mã sau đây làm việc:
std::vector<otherns::Property>
merge_props(const std::vector<otherns::Property> &xs,
const std::vector<otherns::Property> &ys) {
std::vector<otherns::Property> ans = ys;
for (const auto &x : xs) {
if (std::find_if(ans.begin(), ans.end(), [&x](const otherns::Property &y) {
return x == y;
}) == ans.end()) {
ans.push_back(x);
}
}
return ans;
}
Tôi cho rằng đây là một cái gì đó để làm với tra cứu ADL/Koenig nhưng tôi thực sự không hiểu tại sao operator==
của tôi không được tìm thấy. giải pháp tốt nhất là gì nếu tôi muốn sử dụng hình thức đầu tiên, đơn giản hơn của hàm find
?
Thực tế, otherns
xuất phát từ tiêu đề cho thư viện của bên thứ 3 nên tôi không thể đặt toán tử của mình vào tiêu đề đó.
Không tìm thấy vì tìm kiếm phụ thuộc đối số chỉ tìm trong [* "Các không gian tên trong cùng bao quanh trong các lớp được thêm vào tập *"] (http://en.cppreference.com/w/cpp/language/adl). Vì toán tử của bạn nằm trong không gian tên chung, nó không bao giờ được xem xét. – StoryTeller
đó là lý do tại sao bạn phải luôn khai báo các toán tử trong cùng một không gian tên như lớp – bolov
Thư viện mà bạn sử dụng cố ý không cho phép ADL hoặc các tác giả có tội về sự thiếu sót. – StoryTeller