正如其他人已经指出的那样,第一件事是继承不是要走的路。但不是接受的答案建议的复杂包装,我会做一些更简单的事情:为自己的类型实现自己的比较器:
namespace myns {
struct mytype {
int value;
};
bool operator<( mytype const& lhs, mytype const& rhs ) {
return lhs.value < rhs.value;
}
bool operator<( std::shared_ptr<mytype> const & lhs, std::shared_ptr<mytype> const & rhs )
{
// Handle the possibility that the pointers might be NULL!!!
// ... then ...
return *lhs < *rhs;
}
}
魔术,这根本不是魔术,是 Argument Dependent Lookup(又名 Koening Lookup 或 ADL)。当编译器遇到函数调用时,它将添加参数的名称空间以进行查找。如果对象是模板的实例化,那么编译器还将添加用于实例化模板的类型的命名空间。所以在:
int main() {
std::shared_ptr<myns::mytype> a, b;
if ( a < b ) { // [1]
std::cout << "less\n";
} else {
std::cout << "more\n";
}
}
在 [1] 中,因为a
和b
是用户定义类型 (*)的对象, ADL 将启动并将两者都添加std
到 myns
查找集中。然后它将找到operator<
for的标准定义std::shared_ptr
是:
template<class T, class U>
bool std::operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
它还将添加myns
并添加:
bool myns::operator<( mytype const& lhs, mytype const& rhs );
然后,在查找完成后,重载解析开始,它将确定myns::operator<
比std::operator<
调用更好的匹配,因为它是完美匹配,在这种情况下,非模板优先。然后它将调用您自己的operator<
而不是标准的。
如果您的类型实际上是模板,这会变得更加复杂,如果是,请发表评论,我将扩展答案。
(*)这是一个轻微的简化。因为operator<
既可以作为成员函数也可以作为自由函数实现,编译器将在内部检查std::shared_ptr<>
成员operator<
(标准中不存在)和朋友。它还将在内部mytype
寻找friend
功能......等等。但最终它会找到正确的。