với C++ 14, chúng tôi được phép so sánh các phần tử của một số vùng chứa liên kết (như std :: set) với các loại khác so với các phần tử được lưu trữ trong vùng chứa. Đó là nghĩa vụ phải làm việc khi so sánh có is_transparent
được biểu thị dưới dạng một loại (xem ví dụ: std::set::find).Làm cách nào để sử dụng bộ so sánh với loại is_transparent?
Giả sử tôi có một wrapper chuỗi mà thực hiện một số kiểm tra trên một chuỗi (nếu đó là định dạng là định dạng hợp lệ và vân vân - không thực sự quan trọng, nhưng xây dựng nó là đủ nặng mà tôi muốn tránh nó + nó có thể ném ngoại lệ) và nó được lưu trữ trong std :: được thiết lập để có một vùng chứa các giá trị duy nhất. Làm thế nào tôi nên viết một so sánh cho nó? Nếu nó trông giống như dưới đây? Tôi có thể quá tải và sử dụng sw::operator<()
để đạt được điều tương tự không?
class sw
{
public:
explicit sw(const std::string& s) : s_(s) { /* dragons be here */ }
const std::string& getString() const { return s_; }
bool operator<(const sw& other) const { return s_ < other.s_; }
private:
std::string s_;
};
struct Comparator
{
using is_transparent = std::true_type;
bool operator()(const sw& lhs, const std::string& rhs) const { return lhs.getString() < rhs; }
bool operator()(const std::string& lhs, const sw& rhs) const { return lhs < rhs.getString(); }
bool operator()(const sw& lhs, const sw& rhs) const { return lhs < rhs; }
};
int main()
{
std::set<sw, Comparator> swSet{ sw{"A"}, sw{"B"}, sw{"C"} };
std::cout << std::boolalpha << (swSet.find(std::string("A")) != swSet.end()) << std::endl;
}
Tôi tin rằng mã trên nên làm việc như mong đợi, nhưng khi tôi thử nghiệm nó với g ++ 4.9 và kêu vang ++ 3.6, cả hai mang lại các lỗi về việc thiếu chuyển đổi string
-key_type
như nếu chuỗi quá tải của Comparator::operator()
là không bao giờ được tính đến. Tui bỏ lỡ điều gì vậy?
Các phiên bản của libstdC++ (thư viện chuẩn của gcc) đi kèm với g ++ 4.9 đã không thực hiện tra cứu không đồng nhất. Mã của bạn [biên dịch tốt với clang và libC++] (http://coliru.stacked-crooked.com/a/97c0421099d7912d). –
@ T.C .: cảm ơn, điều đó có ý nghĩa và đó là những gì tôi đã sợ ... Tôi đã thử nó với clang và -stdlib = libC++ và nó hoạt động như dự định. Quá xấu mà môi trường mặc định của tôi là g ++ và libstdC++. –
Nó được triển khai trong https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=219888, chưa đầy hai tuần trước. –