Потенциально избыточный компаратор для приведения производного типа shared_ptr - PullRequest
0 голосов
/ 11 марта 2020

В следующем коде наличие cmp и cmp_base кажется мне излишним. Можно ли объединить cmp и cmp_base в один компаратор?

#include <algorithm>
#include <memory>
#include <vector>

using namespace std;

class base {};

class derived : public base {
  public:
    int val;

    static bool cmp(shared_ptr<derived>& d1, shared_ptr<derived>& d2) {
        return d1->val< d2->val;
    }

    static bool cmp_base(shared_ptr<base>& d1, shared_ptr<base>& d2) {
        return static_pointer_cast<derived>(d1)->val < static_pointer_cast<derived>(d2)->val;
    }
};

int main() {
    vector<shared_ptr<derived>> vec1;
    vec1.push_back(make_shared<derived>());
    sort(vec1.begin(), vec1.end(), derived::cmp);

    vector<shared_ptr<base>> vec2;
    vec2.push_back(make_shared<derived>());
    sort(vec2.begin(), vec2.end(), derived::cmp_base);

    return 0;
}

1 Ответ

0 голосов
/ 11 марта 2020

Если вы хотите максимально использовать полиморфизм, вы должны написать компаратор только для shared_ptr<base>&, если это может удовлетворить ваши потребности. Вы должны переопределить виртуальную функцию в базовом классе, которую вы будете использовать, чтобы получить сортируемое значение в производном классе, а затем вызвать ее полиморфно в компараторе shared_ptr<base>&.

Вот краткий пример. Я немного изменил ваш код, чтобы продемонстрировать:

#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>

using namespace std;

class base {
    public:
    virtual int GetValue() = 0;

    static bool cmp(shared_ptr<base>& d1, shared_ptr<base>& d2) {
        return d1->GetValue() < d2->GetValue();
    }
};

class derived : public base {
  public:
    int val;
    derived(int v) {
        val = v;
    }

    virtual int GetValue() {
        return val;
    }
};

class derived2 : public base {
  public:
    int val;

    derived2(int v) {
        val = v;
    }

    virtual int GetValue() {
        return val / 2 + 10;
    }
};

int main() {
    vector<shared_ptr<base>> vec1;
    vec1.push_back(make_shared<derived>(1));
    vec1.push_back(make_shared<derived2>(2));
    vec1.push_back(make_shared<derived>(3));
    sort(vec1.begin(), vec1.end(), base::cmp);

    for (int i = 0; i < vec1.size(); ++i) {
        cout << vec1[i]->GetValue() << ' ';
    }
    cout << endl;

    system("pause");
    return 0;
}
...