एक सदस्य प्रकार के अस्तित्व का पता लगाने के लिए एक अन्य विकल्प void_t
उपयोग करने के लिए है। वैध आंशिक विशेषज्ञताओं जब तक वे डिफ़ॉल्ट पैरामीटर (रों) से मेल खाते हैं सामान्य कार्यान्वयन के लिए बेहतर हैं, हम एक प्रकार है कि void
का मूल्यांकन जब वैध है, और केवल वैध निर्दिष्ट सदस्य मौजूद है चाहते हैं; यह प्रकार आमतौर पर (और, सी ++ 17 के रूप में, कैननिक रूप से) void_t
के रूप में जाना जाता है।
template<class...>
using void_t = void;
अपने संकलक ठीक से समर्थन नहीं करता है (जल्दी सी ++ 14 compilers में उर्फ टेम्पलेट्स में अप्रयुक्त मापदंडों ऊपर void_t
तोड़ने SFINAE सुनिश्चित करने के लिए गारंटी नहीं थी,), एक समाधान उपलब्ध है।
template<typename... Ts> struct make_void { typedef void type; };
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
सी ++ 17 के रूप में, void_t
type_traits
में उपयोगिताओं पुस्तकालय में उपलब्ध है।
#include <iostream>
#include <vector>
#include <type_traits> // For void_t.
template<class T, class V = void>
struct Functor {
void operator()() const {
std::cerr << "general" << std::endl;
}
};
// Use void_t here.
template<class T>
struct Functor<T, std::void_t<typename T::Vec>> {
void operator()() const {
std::cerr << "special" << std::endl;
}
};
struct Foo {
typedef std::vector<int> Vec;
};
int main() {
Functor<Foo> ac;
ac();
}
इसके साथ ही उत्पादन special
, के रूप में इरादा है।
इस मामले में, चूंकि हम सदस्य प्रकार के अस्तित्व की जांच कर रहे हैं, प्रक्रिया बहुत सरल है; यह अभिव्यक्ति SFINAE या type_traits
लाइब्रेरी के बिना किया जा सकता है, जिससे हमें आवश्यक होने पर सी ++ 03 सुविधाओं का उपयोग करने के लिए चेक को फिर से लिखने की अनुमति मिलती है।
// void_t:
// Place above Functor's definition.
template<typename T> struct void_t { typedef void type; };
// ...
template<class T>
struct Functor<T, typename void_t<typename T::Vec>::type> {
void operator()() const {
std::cerr << "special" << std::endl;
}
};
मेरी जानकारी के लिए
, इस, सभी नहीं तो, SFINAE सक्षम सी ++ 03-, सी ++ 11-, सी ++ 14-, या सी ++ 1Z अनुरूप compilers सबसे पर काम करना चाहिए । मानक के पीछे अंतराल वाले कंपाइलर्स से निपटने के दौरान यह उपयोगी हो सकता है, या प्लेटफ़ॉर्म के लिए संकलन करते समय जिनके पास अभी तक C++ 11-संगत कंपाइलर नहीं हैं।
void_t
के बारे में अधिक जानकारी के लिए, cppreference देखते हैं।
'कंपाइलर' टैग को हटा दिया गया है, इसका आमतौर पर संकलन प्रक्रिया के बारे में प्रश्न के लिए उपयोग किया जाता है, जबकि यह प्रश्न सी ++ भाषा के बारे में है। –