C++ 14 đã thêm is_transparent
hỗ trợ cho map
đặt hàng.
struct compare_helper {
X const* px = nullptr;
Y const* py = nullptr;
compare_helper(compare_helper&&)=default;
compare_helper(X const& x):px(&x) {}
compare_helper(Y const& y):py(&y) {}
explicit operator bool()const{return px&&py;}
friend bool operator<(compare_helper&& lhs, compare_helper&& rhs) {
if (!lhs || !rhs) {
return !rhs < !lhs;
}
// TODO: compare lhs and rhs based off px and py
}
};
struct ordering_helper {
using is_transparent=std::true_type;
bool operator()(compare_helper lhs, compare_helper rhs)const{
return std::move(lhs)<std::move(rhs);
}
};
nay xác định lại bạn std::map
:
std::map<X, Details, ordering_helper> detailsMap;
và bạn đã làm xong. Bây giờ, bạn có thể chuyển số Y const&
đến detailsMap.find
hoặc bất kỳ thứ gì.
Hiện tại // TODO: compare lhs and rhs based off px and py
hơi khó chịu.
Nhưng nó phải ghi được.
Nếu bạn cần nhiều lớp khác nhau để có thể so sánh với X
và bạn cần một lớp học lớn compare_helper
với mỗi lần lưu hoặc bạn cần phải xóa thao tác bằng cách nào đó.
Về cơ bản, compare_helper
cần lưu trữ con trỏ đến X
hoặc std::function< int(X const&) >
cho bạn biết nếu X
nhỏ hơn, bằng hoặc lớn hơn thông số khác. (bạn sẽ thấy điều này không thành công khi so sánh số Y
với số Y
hoặc Z
đối với số Y
- trong trường hợp đó, trả về false phải an toàn, vì bạn sẽ chỉ thấy một số không X
trong tìm kiếm bản đồ nhất định).
Chúng ta có thể tách này từ định nghĩa của compare_helper
với một số ADL:
struct compare_helper {
X const* px = nullptr;
using f_helper = std::function< int(X const&) >;
f_helper not_X;
compare_helper(compare_helper&&)=default;
compare_helper(X const& x):px(std::addressof(x)) {}
template<class NotX,
class=std::enable_if_t< std::is_convertible<
decltype(compare_with_X(std::forward<NotX>(notx)))
, f_helper
>{}
>
compare_helper(NotX&& notx):
not_X(compare_with_X(std::forward<NotX>(notx)))
{}
explicit operator bool()const{return px&¬_X;}
friend bool operator<(compare_helper&& lhs, compare_helper&& rhs) {
if (!lhs || !rhs) {
return !rhs < !lhs;
}
if (lhs.px && rhs.px) { return *lhs.px < *rhs.px; }
if (lhs.px && rhs.not_X) { return rhs.not_X(*lhs.px) < 0; }
if (lhs.not_X && rhs.px) { return lhs.not_X(*rhs.px) > 0; }
else return false;
}
};
nay là người dùng cuối chỉ đơn giản là phải ghi đè lên các chức năng miễn phí compare_with_X
trong không gian tên của các loại bạn muốn so sánh với X
để trả về số std::function<int(X const&)>
và bản đồ ở trên cho phép tra cứu từ loại không thuộc loại X
của bạn.
Có thể sử dụng ['std :: find_if'] (http://en.cppreference.com/w/cpp/algorithm/find)? –
'std :: map>' –
Định nghĩa bản đồ không được thay đổi đúng không? Tất cả những gì cần biết là tôi muốn lập chỉ mục bởi các cá thể X. Tôi chỉ đơn giản muốn có thể đến sau và nói "hãy sử dụng trường hợp Y này để tìm kiếm, vì nó có mọi thứ bạn cần để khớp với X" – nappyfalcon