簡體   English   中英

這個模板參數推導是如何工作的?

[英]how does this template parameter deduction work?

編譯器如何在不知道 foo function 的模板參數T類型的情況下決定調用 bar function?

通常當我們調用foo(2)時, T會根據參數2推導為int

這里T是根據傳遞給foo的function bar的參數推導出來的。

#include <iostream>

template<typename T>
void foo(const T& a_) {
    std::cout << a_<< std::endl;
}

void bar(void (*ptr) (const int&)) {
    std::cout << "bar called" << std::endl;
}

int main() {
    bar(foo);
}

編譯器:gcc

當您有一個像foo這樣的重載集時,這意味着foo的名稱查找結果會產生(可能是多個)非模板函數或 function 模板,並且重載集的地址或引用已被采用(此處通過將其作為隱式傳遞function 參數),那么編譯器將嘗試對目標類型進行重載解析(如果有的話)。 這里的目標類型是void(*)(const int&) 整個過程在[over.over]中指定,我將在下面解釋其中的部分內容。

其工作方式是,編譯器將查看重載集中的每個 function 和 function 模板,查看它是否可以將其類型與目標類型匹配,然后將添加那些匹配到一組選定的函數和 function 模板特化過載。 之后再進行一些消除步驟以減少所選重載的集合(例如,檢查是否滿足相關約束並優先使用 function 模板特化的函數,有關所有詳細信息,請參閱[over.over]/5 )並希望最后正好是一個選擇的 function 或 function 模板特化保留,然后將選擇作為原始名稱 ( foo ) 引用的重載解析的結果,並從中獲取地址/引用。

對於非模板 function 匹配意味着目標的 function 類型 ( void(const int&) ) 需要與函數的類型完全相同。 但是這里沒有任何非模板重載。

對於 function 模板,編譯器將嘗試將模板參數推導為 select 與類型匹配並可以添加到所選重載列表的模板的一種特化。 具體來說,這與 function 調用的模板參數推導中的工作原理相同,其中通常有一個 function 參數/參數對的列表以從中推導出模板 arguments,但在這種情況下(假設有目標類型)推導將考慮只有一個參數/參數對,參數是目標類型( void(*)(const int&) ),參數是包含模板參數的模板的 function 類型,即這里的void(const T&) ,調整為指針鍵入void(*)(const T&)因為參數是 function 指針類型。

所以最后編譯器會進行正常的推導

void(*)(const int&)

反對

void(*)(const T&)

決定所選專業化中的T應該是什么。 我想很明顯T應該是int類型才能匹配。 因此,選定的特化將是T = int的特化,它具有與目標類型匹配的 function 類型,並且由於它是唯一選定的重載,並且由於它不會在任何后續步驟中被消除,因此將選擇它作為結果過載決議。

它實際上從 function 指針的類型推導出T的參數,這基本上是如何工作的。

  • 首先編譯看到您調用了bar ,它接受 function 指針,該指針返回 void 並采用一個const int&類型的參數。
  • 然后看到傳遞的參數是function模板。 然后它開始懷疑您是否可以實例化 function,以便它的返回類型和參數列表與 function 指針類型對應。
  • 瞧。 編譯器確實可以通過刪除 cv 限定符和引用來實現這一點。 T似乎是int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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