Как передать пользовательские данные для сравнения функции std :: sort? - PullRequest
0 голосов
/ 20 апреля 2011

Как и qsort(), похоже, что C ++ std::sort() не позволяет передавать пользовательские данные в функцию сортировки.

Например: массив структуры типа struct A { int version; int index; } array[100] должен быть отсортирован по порядку, но с использованием этого массива struct B { int value; } key[100] в качестве ключа сортировки.struct A::index массив индексов key.

Вот нерабочая функция сортировки.Он должен иметь указатель на массив key: 1011

bool comp(struct A *a1, struct A *a2) {
    return key[a1->index].value < key[a2->index].value;
}
1014 * Как этого добиться с помощью C ++?Как передать неглобальные пользовательские данные, такие как key, в функцию сортировки?

Я пытался передать экземпляр объекта как std::sort comp, но, похоже, разрешены только функции qsort().

(В GNU C можно использовать вложенную функцию сравнения для использования переменных области действия, но GNU C ++ не предлагает вложенные функции).

Ответы [ 2 ]

7 голосов
/ 20 апреля 2011

Функторы не должны быть функциями;они могут быть объектами.

struct Comparator {
   Comparator(int* key) : key(key) {};
   bool operator()(struct A *a1, struct A *a2) {
      return key[a1->index].value < key[a2->index].value;
   }

   int* key;
};

/* ... */

std::sort(container.begin(), container.end(), Comparator(<pointer-to-array>));
2 голосов
/ 20 апреля 2011

Вы можете точно сказать sort, как сортировать использование функтора сравнения.

Рабочий пример:

struct Foo
{
    int a_;
    std::string b_;
};

Foo make_foo(int a, std::string b)
{
    Foo ret;
    ret.a_ = a;
    ret.b_ = b;
    return ret;
}
struct ByName : public std::binary_function<Foo, Foo, bool>
{
    bool operator()(const Foo& lhs, const Foo& rhs) const
    {
        return lhs.b_ < rhs.b_;
    }
};

template<class Stream> Stream& operator<<(Stream& os, const Foo& foo)
{
    os << "[" << foo.a_ << "] = '" << foo.b_ << "'";
    return os;
}
int main()
{
    vector<Foo> foos;
    foos.push_back(make_foo(1,"one"));
    foos.push_back(make_foo(2,"two"));
    foos.push_back(make_foo(3,"three"));

    sort(foos.begin(), foos.end(), ByName());

    copy(foos.begin(), foos.end(), ostream_iterator<Foo>(cout, "\n"));

}

Выход:

[1] = 'one'
[3] = 'three'
[2] = 'two'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...