Путаница в том, как использовать функции самоопределения сравнения в std :: sort и std :: priority_queue - PullRequest
3 голосов
/ 18 июня 2019

Я пытаюсь выяснить причины, по которым вы определяете пользовательскую функцию сравнения по-разному для std::sort и std::priority_queue.

например, для std::sort я могу сделать что-то вроде этого:

bool compare(const vector<int>& a, const vector<int>& b)
{
    return a[0] < b[0];
}
class foo
{
public:
    vector<vector<int>> f(vector<vector<int>> list)
    {
        std::sort(list.begin(), list.end(), compare);
        return list;
    }
};


int main()
{
    vector<vector<int>> t = { {2,1},{1,0},{3,7} };
    foo n;

    auto ans = n.f(t);
    for (vector<int> x : ans)
    {
        printf("x[0]: %d , x[1]: %d \n", x[0], x[1]);
    }
    return 0;
}

после запуска кода результат:

x [0]: 1, x [1]: 0

x [0]: 2, x [1]: 1

x [0]: 3, x [1]: 7

Однако, если я определю другую функцию в foo следующим образом:

vector<vector<int>> f1(vector<vector<int>> list)
{
    std::priority_queue<vector<int>, vector<vector<int>>, compare> pq;
}

Компилятор не позволит мне сделать это. Простой способ обойти это - создать структуру внутри класса следующим образом:

struct Compare
{
    bool operator()(const vector<int>& a, const vector<int>& b)
    {
        return a[0] < b[0];
    }
};

Вот что у меня есть: Из en.cppreference.com std::sort передают объект функции сравнения, но priority_queue передает тип сравнения. Я предполагаю, что это может быть причиной того, что я не могу использовать ту же функцию сравнения для приоритетной очереди.

Другая мысль состоит в том, что, поскольку std::sort является функцией, а priority_queue является контейнером, поэтому нам нужно сделать его другим?

Это все, что у меня есть сейчас.

Больше всего меня беспокоит то, почему они ведут себя так по-разному? Какова основная причина, по которой это должно быть иначе? почему мы должны отличаться?

p.s. У кого-нибудь есть какие-нибудь хорошие книжные рекомендации для глубокого объяснения STL и концентрации внимания на объяснении кода STL и почему они сделали это таким образом?

1 Ответ

5 голосов
/ 18 июня 2019

Вы указываете compare в качестве третьего аргумента шаблона для std::priority_queue, который не является правильным именем типа.Вам необходимо указать его как тип указателя на функцию (и передать указатель на функцию в качестве аргумента функции).Например,

std::priority_queue<vector<int>, vector<vector<int>>, decltype(compare)*> pq(compare);

или

std::priority_queue<vector<int>, vector<vector<int>>, bool (*)(const vector<int>&, const vector<int>&)> pq(compare);

std::sort - это шаблон функции, поэтому, когда вы можете передать compare в качестве аргумента функции и параметр шаблона может быть автоматически выведен (как тип указателя на функцию);std::priority_queue - это шаблон класса, поэтому вам нужно явно указать аргумент шаблона , вам просто нужно правильно указать тип (как тип указателя на функцию, так же, как и тип шаблонный параметр тип std::sort, который выводится автоматически).

РЕДАКТИРОВАТЬ

Начиная с C ++ 17 у нас есть классвычет аргумента шаблона , и затем вы можете использовать его как

vector<vector<int>> f1(vector<vector<int>> list)
{
    // deduced T=vector<int>, Container=vector<vector<int>>, Compare=bool (*)(const vector<int>&, const vector<int>&)
    std::priority_queue pq(compare, list);
    return ...
}

, тогда нам не нужно указывать аргументы шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...