माइक्रोसॉफ्ट के प्रलेखन there वहाँ कीचड़ के रूप में स्पष्ट है मत भूलना। इसके बजाय this का उपयोग करें।
फार्म की एक अनाम डिफ़ॉल्ट पैरामीटर के साथ एक समारोह टेम्पलेट प्रदान करना: - केवल मामले में और -
typename enable_if<your_condition, void **>::type = nullptr
(एमएस मुंशी पता चलता है के रूप में), मामले में उपयोगी है आप इच्छा के कई भार के लिखने के लिए विभिन्न व्यवहारों के साथ फ़ंक्शन टेम्पलेट जो टेम्पलेट तर्कों में से एक या अधिक द्वारा नियंत्रित होते हैं। फिर, एक शर्त टेम्पलेट तर्क (रों) पर एक उपयुक्त आवश्यकता व्यक्त करते your_condition
की जगह, आप SFINAE सिद्धांत विशिष्ट अधिभार कि आप दिया टेम्पलेट तर्क के लिए instantiated होना चाहते हैं का चयन करने के भर्ती कर सकते हैं।
एसएफआईएनएई पैरामीटर - चलो इसे कॉल करें - तत्काल कार्य द्वारा अप्रयुक्त है; यह फ़ंक्शन टेम्पलेट ओवरलोड रिज़ॉल्यूशन में 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)
पर कॉल करें और आपको स्क्वायरिंग मिलती है।
यहां एमएस का नमूना SFINAE पैरामीटर अनिवार्य रूप से लंबा है।
template< bool B, class T = void >
struct enable_if;
प्रति सी ++ 11 मानक के रूप में और बाद में
void
करने के लिए
, चूक T
। की तो जैसे:
typename std::enable_if<some_condition, void **>::type = nullptr
रूप में अच्छी तरह संक्षिप्त किया जा सकता है:
typename std::enable_if<some_condition>::type * = nullptr
और सी ++ 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
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) उदाहरण के लिए अधिभार संकल्प का उपयोग कर यह उपयोगी हो सकता है: 10 मामले है कि आप अपने पोस्ट में पर इशारा किया है करने के लिए एक SFINAE समारोह टेम्पलेट पैरामीटर को लागू करने के लिए, आप की तरह लिखते थे। – BartoszKP
'omull' भाग तक नहीं पहुंचा जा सकता है। – Jarod42
enable_if फ़ंक्शन को सक्षम करता है, पैरामीटर नहीं। –