C ++ STL: использование производного виртуального класса в качестве «строгого слабого порядка» для std :: sort () - PullRequest
4 голосов
/ 04 мая 2011

Я ударил стену, используя std :: sort (). У меня есть чистый виртуальный класс (с именем Compare), из которого происходит вызов метода (с именем MyComp). Я использую чистый виртуальный класс для прототипа моего API:

void Object::DoSort(Compare &comp) {
    std::sort(this->mKeys.begin(),this->mKeys.end(), comp);
}

звонящий:

class MyComp: public Compare {
    bool operator()(const Row *r1, const Row *r2)  { ... }
} cmp;
...
obj->DoSort(cmp);

Компилятор g ++ в Linux жалуется, что: «не удается выделить объект типа« Сравнить », поскольку тип« Сравнить »имеет абстрактные виртуальные функции»

Даже если я изменю Compare на виртуальный (не чистый), std::sort() все равно вызывает код Compare::operator() вместо MyComp::operator().

Вызов cmp (r1, r2) прекрасно компилируется и возвращает правильный результат.

Я должен сделать что-то не так, или я не понимаю. Помогите, пожалуйста!

1 Ответ

8 голосов
/ 04 мая 2011

std::sort (и другие функции STL) принимают объекты компаратора по значению , поэтому ваш объект копируется, но производная часть (включая его vtbl) "вырезана".

Вы можете обернуть свой объект в прокси:

class Proxy
{
private:
    Compare &cmp;
public:
    Proxy(Compare &cmp) : cmp(cmp) {}
    bool operator()(const Row *r1, const Row *r2) { return cmp(r1, r2); }
};


...

MyCompare cmp = MyCompare();

std::sort(x.begin(), x.end(), Proxy(cmp));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...