![](/img/trans.png)
[英]How does template type deduction work with an overloaded function as the parameter
[英]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&
類型的參數。T
似乎是int
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.