簡體   English   中英

為什么向量被用作優先隊列的第二個參數?

[英]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);

我的問題

  1. 為什么priority_queue的第二個參數是一個vector 這是什么意思,什么時候需要指定第二個參數?
  2. 在方法 2 中,為什么這個 lambda 需要decltype
  3. 方法2中,為什么leaderBoard需要用(myComp)初始化
  4. 在方法 2 中,為什么不能直接將我的 lambda 指定為第三個參數?
  5. A.second > B.secondA.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>> )將是默認存在。

  1. 為什么priority_queue的第二個參數是向量? 這是什么意思,什么時候需要指定第二個參數?

我們不需要明確指定它。 第二個模板參數是用於數據內部表示的類型。 std::priority_queue是一個容器適配器,這意味着它本身不是一個容器 - 它使用一些其他容器並用某種實用程序包裝它。

  1. 在方法 2 中,為什么這個 lambda 需要 decltype?

因為你需要提供一個type myCompare是一個struct ,所以它是一個類型的名稱。 myComp不是一個類型,它是一個變量。 你想得到它聲明的類型嗎? 使用decltype

  1. 在方法 2 中,為什么需要使用(myComp)初始化 object 排行榜?

因為你不能默認構造一個 object 給定decltype的 lambda ( 這在 C++20 中得到了放松)。 您需要使用以下構造函數:

explicit priority_queue(const Compare& compare)
    : priority_queue(compare, Container()) { }

它期望將用作比較器的可調用對象(在本例中為 lambda)。

  1. 在方法 2 中,為什么不能直接將我的 lambda 指定為第三個參數?

你的意思是作為第三個template參數? 因為到目前為止,lambdas 不能在未評估的上下文中使用,而為模板提供類型就是其中之一。

5.1。 A.second > B.secondA.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM