首先了解一個概念:SFINAE : substitution failure is not an error, 替代失敗不是錯誤
template<typename T>
typename std::enable_if<sizeof(T) > 4>::type
foo()
{
}
std::enable_if<>會計算作爲第一個模板參數傳遞的給定編譯時表達式
如果expression爲true, 則std::enable_if<>::type得到一個類型:
- 如果enable_if只有一個模板參數, 則type成員得到的類型是void
- 否則, type成員得到的類型是第二個模板參數的類型
如果expression爲false, type成員未定義. 由於模板的一個功能叫做SRINAE,
就會使這個帶有enable_if表達式的模板函數在匹配時被忽略.
C++14開始, 可以用 _t的後綴版本來簡寫::type
template<typename T>
std::enable_if_t<sizeof(T) > 4>
foo
{
}
template<typename T>
std::enable_if_t<sizeof(T) > 4, T>
foo
{
}
在template和函數名之間寫這個會顯得很笨拙, 因此, 一般都會選擇帶有默認值的附加函數模板參數:
template<typename T,
typename = std::enable_if<sizeof(T) > 4>::type>
void foo()
{
}
如果表達式爲true, 會擴展爲:
template<typename T,
typename = void>
void foo()
{
}
還可以用using來簡寫:
template<typename T>
using EnableIfSizeGreater4 = std::enable_if<sizeof(T) > 4>::type;
template<typename T, typename = EnableIfSizeGreater4<T>>
void foo
{
}