[英]SFINAE template specialization matching rule
我正在學習具有類/結構模板專業化的SFINE
,但我對一個細微示例中的匹配規則感到有些困惑。
#include <iostream>
template <typename T, typename = void>
struct Foo{
void foo(T t)
{
std::cout << "general";
}
};
template <typename T>
struct Foo<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
void foo(T t)
{
std::cout << "specialized";
}
};
int main()
{
Foo<int>().foo(3);
return 0;
}
這符合預期並打印出 special ,但是如果我將specialized
函數稍微更改為以下內容:
template <typename T>
struct Foo<T, typename std::enable_if<std::is_integral<T>::value, int>::type>
{
void foo(T t)
{
std::cout << "specialized";
}
};
然后它打印出general
。 第二個實現中發生了哪些變化,使其不那么“專業化”?
將你的眼球重新聚焦幾行,到這部分:
template <typename T, typename = void>
struct Foo{
這意味着當這里調用此模板時:
Foo<int>().foo(3);
這最終調用了以下模板: Foo<int, void>
。 畢竟,默認情況下,這就是第二個模板參數。
第二個模板參數不是一些瑣碎的小細節,被掃到地毯下。 調用模板時,必須指定或推導其所有參數。 如果沒有,如果他們有一個默認值,那就挽救了一天。
SFINAE 經常利用默認模板參數。 現在,讓我們重新審視您提出的模板修訂:
template <typename T>
struct Foo<T, typename std::enable_if<std::is_integral<T>::value, int>::type>
這種特化的效果是特化中的第二個模板參數是int
,而不是void
。
但是Foo<int>
仍將使用默認的void
作為第二個模板參數,因為那是第二個模板參數的默認值。 因此,只有一般定義會匹配,而不是任何專業化。
並不是它不那么專業,它不再匹配模板實例化。 第二個類型參數默認為void
,但由於std::enable_if
現在別名為int
,特化不再匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.