簡體   English   中英

為什么不專門化 function 模板? (問答)

[英]Why not specialize function templates? (Q&A)

我將嘗試組織這個問題,作為問答,並希望有同事能從中有所收獲。

首先先回答一個簡單的問題,這個程序的output是什么?

#include <iostream>

template<class T>
void f(T) { std::cout << 1; }

template<>
void f<>(int*) { std::cout << 2; }

template<class T>
void f(T*) { std::cout << 3; }

int main() {
    int *p = nullptr; 
    f( p );
}

如果您的答案是 3,那么恭喜,您可以跳過此問答。

對於其他所有人:

我個人認為output應該是2,如果你到了這一步,我猜你也是。
現在讓我們深入一點。

名稱 f 被兩個 function 模板void f(T)void f(T*)重載。 注意,重載解析只考慮 function 模板,而不是顯式特化void f<>(int*) ,對於重載解析,首先我們為每個 ZC1C425268E68385D1AB5074D1AB507E6FB4DABD882E7DZ 推導出模板 arguments ,並得到 TTA 中的第一個T = int * F1AB5074 T = int第二個。

function 模板都是可行的,但哪一個最好? 根據[over.match.best]§16.3.3¶1 ,如果 function 模板更專業,則它比另一個 function 模板更匹配:

a viable function F1 is defined to be a better function than another viable function F2 if (...) the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 17.5.6.2

部分排序的過程在這里引用有點長,並不是這個問題的關鍵。 但總而言之, f(T*)接受的任何內容也將被f(T)接受,但反之則不然。 所以f(T*)更專業。

現在我們知道 function 模板void f(T*)是通過重載決議選擇的,我們可以開始考慮專門化。 哪個 function 模板是void f<>(int*)的特化? [temp.expl.spec]§17.7.3¶3

顯式特化的 function 模板 (...) 的聲明應在顯式特化的聲明之前。

因此,顯式特化 void f<>(int*)void f(T)的特化,因為這是在它之前的唯一 function 模板聲明。 然而,重載分辨率選擇了另一個 function 模板void f(T*) ,我們改為將其稱為隱式實例化的特化,打印 3。

更多內容請參考 Herb Sutter 的文章

暫無
暫無

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

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