![](/img/trans.png)
[英]Why do we need to add a vector as an argument in priority queue declaration?
[英]Why is Vector used as a second argument to Priority Queue?
為什么當priority_queue 用於單一數據類型時,比如'int',我們這樣初始化它: priority_queue<int>
; 但是,當它用一對初始化時,我們添加第二個類型為向量priority_queue<pair<int,int>, vector<pair<int,int>>>
的參數?
此外,我注意到添加指定排序的第三個參數的幾種方法。
方法 1 - 結構
struct myCompare {
bool operator()(const pair<int, int>& A, const pair<int, int>& B) {
return A.second < B.second;
}
};
priority_queue<pair<int, int>, vector<pair<int, int>>, myCompare> leaderBoard;
方法 2 - Lambda
auto myComp = [](const pair<int, int>& A, const pair<int, int>& B)
{return A.second < B.second;};
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(myComp)> leaderBoard(myComp);
我的問題
priority_queue
的第二個參數是一個vector
? 這是什么意思,什么時候需要指定第二個參數?decltype
?leaderBoard
需要用(myComp)
初始化A.second > B.second
和A.second < B.second
什么區別? 你怎么記得哪個是升序,哪個是降序?為什么當
priority_queue
與單一數據類型一起使用時,比如'int',我們這樣初始化它:priority_queue<int>
[...]?
因為std::priority_queue
是一個 class 模板,定義如下:
template<
class T,
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>
> class priority_queue;
如您所見,您可以僅提供T
實例化此 class ,因為類型的 rest 將被默認。 您可以在此處閱讀有關模板默認 arguments 的更多信息。
但是,當它用一對初始化時,我們添加第二個類型為向量
priority_queue<pair<int,int>, vector<pair<int,int>>>
的參數?
因為有人想要明確。 priority_queue<pair<int, int>>
等價於priority_queue<pair<int,int>, vector<pair<int,int>>>
,因為第二個模板類型( vector<pair<int, int>>
)將是默認存在。
- 為什么priority_queue的第二個參數是向量? 這是什么意思,什么時候需要指定第二個參數?
我們不需要明確指定它。 第二個模板參數是用於數據內部表示的類型。 std::priority_queue
是一個容器適配器,這意味着它本身不是一個容器 - 它使用一些其他容器並用某種實用程序包裝它。
- 在方法 2 中,為什么這個 lambda 需要 decltype?
因為你需要提供一個type 。 myCompare
是一個struct
,所以它是一個類型的名稱。 myComp
不是一個類型,它是一個變量。 你想得到它聲明的類型嗎? 使用decltype
。
- 在方法 2 中,為什么需要使用
(myComp)
初始化 object 排行榜?
因為你不能默認構造一個 object 給定decltype
的 lambda ( 這在 C++20 中得到了放松)。 您需要使用以下構造函數:
explicit priority_queue(const Compare& compare)
: priority_queue(compare, Container()) { }
它期望將用作比較器的可調用對象(在本例中為 lambda)。
- 在方法 2 中,為什么不能直接將我的 lambda 指定為第三個參數?
你的意思是作為第三個template
參數? 因為到目前為止,lambdas 不能在未評估的上下文中使用,而為模板提供類型就是其中之一。
5.1。
A.second > B.second
和A.second < B.second
什么區別?
差別相當明顯。 一個檢查A.second
是否大於第二個參數,另一個檢查是否相反。 它通常用於排序(用於比較元素)。
5.2 你怎么記得哪個是升序,哪個是降序?
這很容易 - C++
的概念是在左側參數和右側參數之間使用<
,如下所示: left_hand_side < right_hand_side
。
為什么priority_queue的第二個參數是向量?
您可以使用任何滿足某些要求的容器。 vector
是一個合理的默認選擇。
這是什么意思,什么時候需要指定第二個參數?
如果要更改其默認值,或者要指定第三個。 std::priority_queue<std::pair<int,int>>
是沒有指定第二個參數的有效類型。
在方法 2 中,為什么這個 lambda 需要 decltype?
如果要使用自定義比較器,則必須將其類型指定為第三個模板參數。 每個 lambda 都有自己獨特的類型,獲得它的唯一方法是通過decltype
。
方法2中,為什么object排行榜需要用(myComp)初始化
因為可以默認構造基於struct
的比較器,但基於 lambda 的比較器不能。 相關的構造函數是
priority_queue() : priority_queue(Compare(), Container()) { }
priority_queue(const Compare& compare) : priority_queue(compare, Container()) { }
如果您不提供compare
,則使用Compare()
。 myCompare()
是一個有效值,而decltype(myComp)()
不是。
在方法 2 中,為什么不能直接將我的 lambda 指定為第三個參數?
您需要一個類型,而不是該類型的值。
A.second > B.second 和 A.second < B.second 有什么區別?
交換 arguments 的順序(或等價的<
和>
)將最小堆轉換為最大堆,反之亦然,即該順序確定.top()
將返回哪個元素,最小或最大。
方法2中,為什么object排行榜需要用(myComp)初始化
這取決於您使用的 C++ 標准。 在 C++20 之前,您需要將由 lambda 表達式創建的仿函數傳遞給priority_queue
構造函數,因為在 C++20 之前的 lambdas 不是默認可構造的。
從 C++20 開始,您可以編寫:
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(myComp)> leaderBoard;
它會正常工作,因為編譯器知道 lambda 的類型 - 由decltype(myComp)
指定,並且它可以調用其默認 ctor。
在方法 2 中,為什么不能直接將我的 lambda 指定為第三個參數?
是的,你可以,但你仍然需要使用decltype
來獲取比較器類型:
priority_queue<pair<int, int>, vector<pair<int, int>>,
decltype( [](const pair<int, int>& A, const pair<int, int>& B)
{return A.second < B.second;} ) > leaderBoard;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.