微軟的文檔there 存在都不清晰。改爲使用this。
提供了一個函數模板與形式的一位不願透露姓名的默認參數:
typename enable_if<your_condition, void **>::type = nullptr
(如MS隸建議),就能發揮作用 - 只有在外殼和 - 你希望 寫的多個重載具有不同行爲的函數模板 ,它們由一個或多個模板參數控制。然後,通過 與表達上的模板參數(一個或多個)適當 要求的條件更換your_condition
,你可以爭取SFINAE 原則來選擇要實例化 給出模板參數的具體超載。
SFINAE參數 - 我們稱之爲 - 爲 未被實例化的函數使用;它僅存在於函數模板 重載解析中激發SFINAE。因此它可能是無名的,因此它必須默認爲: 當您調用函數模板時,它不能強制您提供額外的無用參數。
例如:
#include <type_traits>
#include <iostream>
template <typename T>
T foo(T && t,
typename std::enable_if<std::is_same<T,int>::value, void **>::type = nullptr)
{
std::cout << "Doubling " << t << " gives " << (t + t) << std::endl;
return t + t;
}
template <typename T>
T foo(T && t,
typename std::enable_if<!std::is_same<T,int>::value, void **>::type = nullptr)
{
std::cout << "Squaring " << t << " gives " << (t * t) << std::endl;
return t * t;
}
using namespace std;
int main()
{
cout << foo(2) << endl;
cout << foo(3.3) << endl;
return 0;
}
輸出是:
Doubling 2 gives 4
4
Squaring 3.3 gives 10.89
10.89
在功能模板foo
這兩種過載,第一個加倍它是 類型T
參數,第二個正方形它的參數,並且使用SFINAE 參數來確定如果T
是,則將實例化加倍過載,否則將選擇平方過載。
當T
是int
,條件:
!std::is_same<T,int>::value
控制所述平方過載的SFINAE參數爲假。因此 類型說明符:
typename std::enable_if<!std::is_same<T,int>::value, void **>::type = nullptr
無法編譯。這是模板解析中的替代失敗。將 int
替換爲T
中的平方過載爲不可行。所以平方過載從運行中消除了 ,並且只剩下加倍過載來實例化函數調用 。
當T
是(說)double
,而不是int
,則剛好相反發生 ,只有平方超載生存模板的分辨率。撥打電話foo(2)
,你會倍增。撥打電話foo(3.3)
即可。
MS的標本SFINAE參數在這裏是不必要的冗長。
template< bool B, class T = void >
struct enable_if;
按C++ 11標準和更高版本,默認T
到void
。所以類似的:
typename std::enable_if<some_condition, void **>::type = nullptr
能以及簡寫爲:
typename std::enable_if<some_condition>::type * = nullptr
,並作爲C++ 14的標準有:
template< bool B, class T = void >
using enable_if_t = typename enable_if<B,T>::type
因此同樣SFINAE參數進一步縮短爲:
std::enable_if_t<some_condition> * = nullptr
應用一個SFINAE函數模板參數,你已經在你的 後做了個手勢的情況下,你會寫類似的:
enum ops {
add,
multiply
};
template<ops Op>
int op(int const & lhs, int const & rhs,
std::enable_if_t<Op == add> * = nullptr)
{
return lhs + rhs;
}
template<ops Op>
int op(int const & lhs, int const & rhs,
std::enable_if_t<Op == multiply> * = nullptr)
{
return lhs * rhs;
}
...
auto i = op<add>(2,3);
auto j = op<multiply>(2,3);
...
// C++14
使用重載例如當(AB),它可以是有用的。 – BartoszKP 2015-03-13 19:08:56
無法到達'omull'部分。 – Jarod42 2015-03-13 19:22:04
enable_if啓用該功能,而不是參數。 – 2015-03-13 19:39:23