In C++14 http://en.cppreference.com/w/cpp/container/set/find, std::set<Key>::find
is a template
函数如果Compare::is_transparent
存在。您传入的类型不需要是Key
,相当于您的比较器下的值。
所以写一个比较器:
template<class T>
struct pointer_comp {
typedef std::true_type is_transparent;
// helper does some magic in order to reduce the number of
// pairs of types we need to know how to compare: it turns
// everything into a pointer, and then uses `std::less<T*>`
// to do the comparison:
struct helper {
T* ptr;
helper():ptr(nullptr) {}
helper(helper const&) = default;
helper(T* p):ptr(p) {}
template<class U, class...Ts>
helper( std::shared_ptr<U,Ts...> const& sp ):ptr(sp.get()) {}
template<class U, class...Ts>
helper( std::unique_ptr<U, Ts...> const& up ):ptr(up.get()) {}
// && optional: enforces rvalue use only
bool operator<( helper o ) const {
return std::less<T*>()( ptr, o.ptr );
}
};
// without helper, we would need 2^n different overloads, where
// n is the number of types we want to support (so, 8 with
// raw pointers, unique pointers, and shared pointers). That
// seems silly:
// && helps enforce rvalue use only
bool operator()( helper const&& lhs, helper const&& rhs ) const {
return lhs < rhs;
}
};
然后使用它:
typedef std::set< std::unique_ptr<Foo>, pointer_comp<Foo> > owning_foo_set;
now, owning_foo_set::find
会接受unique_ptr<Foo>
or Foo*
or shared_ptr<Foo>
(或任何派生类Foo
)并找到正确的元素。
在 C++14 之外,您被迫使用map
to unique_ptr
方法,或等效的东西,作为签名find
限制过于严格。或者自己写set
相等的。