Как мы все знаем, инициализация списка появилась в C++ из C++11. В большинстве случаев это легко понять. Однако при использовании инициализации списка для создания объекта класса это всегда сбивает меня с толку.
Я не понимаю, как работает инициализация списка в следующем коде и как он генерирует объекты состояния.
Из push-документа мы можем узнать, что его тип аргумента — const Status& value
или Status&& value
. поэтому в q.push({node->val, node})
{node->val, node} будет приведено к статусу. Я не знаю, как это завершено.
Кто-нибудь может помочь? Любая помощь приветствуется.
// This is a code snippet from the official LeetCode solution.
class Solution {
public:
struct Status {
int val;
ListNode *ptr;
bool operator < (const Status &rhs) const {
return val > rhs.val;
}
};
priority_queue <Status> q;
ListNode* mergeKLists(vector<ListNode*>& lists) {
for (auto node: lists) {
if (node) q.push({node->val, node});
}
ListNode head, *tail = &head;
while (!q.empty()) {
auto f = q.top(); q.pop();
tail->next = f.ptr;
tail = tail->next;
if (f.ptr->next) q.push({f.ptr->next->val, f.ptr->next});
}
return head.next;
}
};
@HolyBlackCat, поэтому ему нужно вызывать конструктор для создания объекта Status?
Что ты имеешь в виду? Технически он не вызывает конструктор Status
(это называется «агрегатной инициализацией» и не использует конструкторы), но я не понимаю, почему это имеет значение, поскольку ему придется вызывать конструкторы отдельных членов независимо.
@HolyBlackCat Спасибо, под вашим руководством я полностью понял вопрос. Еще раз спасибо.
Ответ уже был указан разработчиками в комментариях. Чтобы людям, которые запутались в этом вопросе, было легче понять ответ. Я повторю ответ из комментариев здесь.
Процесс передачи фактических аргументов параметрам функции — это инициализация параметров, а не назначение. И статус является агрегатным типом (согласно агрегатной инициализации), поэтому в операторе q.push({node->val, node})
есть агрегатная инициализация, которая использует {node-> val, node} для инициализации агрегатного типа Status.
Это ничем не отличается от
Status s{f.ptr->next->val, f.ptr->next};
. Поскольку уStatus
нет пользовательских конструкторов, это просто упорядочивает все поля.