【问题标题】:Sort a std::vector by type按类型对 std::vector 进行排序
【发布时间】:2014-04-15 13:50:23
【问题描述】:

我正在观看http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly,大约在 36 分钟左右,他们讨论了如果您要在集合上调用虚方法,按其元素类型对集合进行排序的好处。

给定

class Base {};
class Der1 : public Base {};
class Der2 : public Base {};
class Der3 : public Base {};

vector<Base *> myVector;

您如何对myVector 进行排序,以使每种类型的元素都相邻?

有没有什么方法可以在不使用虚函数来识别每个派生类型的情况下做到这一点? (也许使用typeid?)

【问题讨论】:

  • Herb Sutter 最近的Build 2014 talk 也涵盖了这种优化。像往常一样,这是一块很棒的手表。

标签: c++ sorting inheritance


【解决方案1】:

您可以为此使用type_index。您从 typeid 运算符返回的 type_info 对象构造一个。它是一个具有重载关系运算符的类,具有明确定义的顺序,因此它可用作关联容器等中的键类型。

这是一个例子:

#include <typeinfo>
#include <typeindex>
#include <vector>
#include <algorithm>
#include <iostream>

struct Base {
    virtual ~Base() {}
    virtual const char* who() = 0;
};
struct D1 : Base { const char* who() { return "D1\n"; } };
struct D2 : Base { const char* who() { return "D2\n"; } };
struct D3 : Base { const char* who() { return "D3\n"; } };

int main()
{
    std::vector<Base*> vec { new D2, new D1, new D3, new D3, new D1, new D2 };
    std::sort( vec.begin(), vec.end(),
    [](const Base* p1, const Base* p2)
    {
        return
            std::type_index(typeid(*p1)) <
            std::type_index(typeid(*p2));
    });

    for (auto p : vec) { std::cout << p->who(); }
}

输出是:

D1
D1
D2
D2
D3
D3

【讨论】:

  • 值得注意的是,它与智能指针一样好用:)
【解决方案2】:

您指定比较函数。有关这方面的更多详细信息,请参阅例如 Sorting an STL vector on two values

在比较函数中,你可以写任何你想要的。它可以比较对象的任何属性。特别是,它可以比较通过虚函数得到的一个特定值,例如getType(),它可能在Der1中返回1,在Der2中返回2,在Der 3中返回3。

【讨论】:

    【解决方案3】:

    你可以实现一个虚函数,比如prio,它返回类型之间的优先级(int); prio 将在派生类中适当地实现。然后实现一个比较器,它会在 Base 的两个实例上评估 prio 以比较它们。

    【讨论】:

      【解决方案4】:

      这些只是可能性,对此没有一个真正的答案。

      排序?

      排序的主要问题是找到用于排序的键。如果您愿意,这是“第一阶段”。阶段 2 使用标准库中的通用排序,通常比阶段 1 更容易。

      键控

      一种可能性是使用typeid / type_info

      type_info 的实例定义了operator ==operator !=,以及一个hash_code 成员函数。

      排序

      使用标准算法中的通用排序算法。作为排序的关键,您可以使用例如hash_code 函数返回的值。

      【讨论】:

        猜你喜欢
        • 2010-09-19
        • 2011-06-04
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 2021-01-21
        • 1970-01-01
        • 2016-10-22
        相关资源
        最近更新 更多