我有一个看似简单的问题,但我找不到一个优雅的解决方案。
我正在使用链接列表,我需要对其进行两次排序:
我存储在列表中的对象继承自抽象列表项基类。
问题在于使用第二个参数。我不想在列表项基类中为它编写纯虚拟访问器,因为我稍后在列表中存储了一些其他对象,这些对象也从列表项基类继承,但是第二个访问器对于他们。
我缺少一个干净的解决方案吗?
答案 0 :(得分:3)
使用谓词:
std::list<Base*> myList; /* populate */
myList.sort([](Base * const p1, Base * const p2) -> bool
{ return static_cast<Derived*>(p1)->compare_with(*p2); }
);
这假设在排序运行期间,所有元素实际上都指向Derived
,它们具有成员函数foo
(甚至不需要是虚拟的),它返回一个bool。
您当然可以以您喜欢的任何方式调整谓词的详细信息。如果您使用的是旧编译器,还可以使用传统的拼写谓词类替换lambda表达式。
如果您无法确定所有元素实际上是Derived
类型,那么您可以使用dynamic_cast
代替,但是您必须考虑一种方法来订购所有元素无与伦比的对象。在这种情况下,最好先将范围划分为Derived
和非{,1}的事物,并且只对前者进行排序。
答案 1 :(得分:1)
如果我理解正确,你就是这样的:
class Base {
public:
int getParam1() const { ... };
virtual void foo() =0; // this is an abstract class
virtual ~Base() { ... }
}
class Derived : public Base {
public:
int getParam1() const { ... }
int getParam2() const { ... }
}
你某处有一个std::list<Base*> myList
。第一次要对列表进行排序时,可以执行以下操作:
sort(list.begin(),list.end(),[](const Base*v1,const Base*v2) {
return v1->getParam1()<v2->getParam1();
});
对于第二种类型,您需要使用特定于类Derived
的内容。您不希望将纯虚拟访问者getParam2()
添加到Base
&amp;在Derived
中实现它。但是,如果您知道您的列表中只包含 派生对象,则可以毫无问题地使用强制转换:
sort(list.begin(),list.end(),[](const Base*b1,const Base*b2) {
const Derived * d1 = dynamic_cast<const Derived*>(b1);
const Derived * d2 = dynamic_cast<const Derived*>(b2);
return d1->getParam2() < d2->getParam2();
});
请注意,如果列表中的对象不是Derived
,则dynamic_cast将返回nullptr
,以便您可以安全地检查它。
答案 2 :(得分:0)
我是否正确理解您想要对某些容器(您自己的设计)的元素进行排序,以获取如何在这些元素之间进行比较的不同版本?如果是这样,只需使用比较函数/函数提供排序算法。