मैं Tकिसी विशिष्ट वर्ग के उपवर्ग होने के लिए टेम्पलेट पैरामीटर को कैसे बाध्य कर सकता हूं Baseclass? कुछ इस तरह:
template <class T : Baseclass> void function(){
T *object = new T();
}
मैं Tकिसी विशिष्ट वर्ग के उपवर्ग होने के लिए टेम्पलेट पैरामीटर को कैसे बाध्य कर सकता हूं Baseclass? कुछ इस तरह:
template <class T : Baseclass> void function(){
T *object = new T();
}
Tव्युत्पन्न है Baseclass। अब तक, वह चेक निहित है, और अधिभार संकल्प के लिए दिखाई नहीं दे रहा है। लेकिन अगर कहीं भी ऐसा निहितार्थ नहीं किया गया है, तो कृत्रिम प्रतिबंध का कोई कारण नहीं प्रतीत होता है।
जवाबों:
इस मामले में आप यह कर सकते हैं:
template <class T> void function(){
Baseclass *object = new T();
}
यह संकलित नहीं करेगा यदि T, बास्कल का उपवर्ग नहीं है (या T , बास्कल है)।
C ++ 11 संगत कंपाइलर के साथ, आप कुछ इस तरह कर सकते हैं:
template<class Derived> class MyClass {
MyClass() {
// Compile-time sanity check
static_assert(std::is_base_of<BaseClass, Derived>::value, "Derived not derived from BaseClass");
// Do other construction related stuff...
...
}
}
मैं एक CYGWIN पर्यावरण के अंदर gcc 4.8.1 संकलक का उपयोग करके इसका परीक्षण कर चुका हूं - इसलिए इसे * nix वातावरण में भी काम करना चाहिए।
template<class TEntity> class BaseBiz { static_assert(std::is_base_of<BaseEntity, TEntity>::value, "TEntity not derived from BaseEntity");...
रनटाइम पर कम बेकार कोड को निष्पादित करने के लिए आप यहां देख सकते हैं: http://www.stroustrup.com/bs_faq2.html#constraints जो कुछ कक्षाएं प्रदान करता है जो संकलित समय परीक्षण कुशलतापूर्वक करते हैं, और अच्छे त्रुटि संदेश उत्पन्न करते हैं।
विशेष रूप से:
template<class T, class B> struct Derived_from {
static void constraints(T* p) { B* pb = p; }
Derived_from() { void(*p)(T*) = constraints; }
};
template<class T> void function() {
Derived_from<T,Baseclass>();
}
unused variable 'p'और unused variable 'pb'?
(void)pb;बाद जोड़ें B* pb = p;।
आपको अवधारणाओं की आवश्यकता नहीं है, लेकिन आप SFINAE का उपयोग कर सकते हैं:
template <typename T>
boost::enable_if< boost::is_base_of<Base,T>::value >::type function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
ध्यान दें कि यह फ़ंक्शन को केवल तभी पूरा करेगा जब शर्त पूरी हो जाएगी, लेकिन यह एक समझदार त्रुटि प्रदान नहीं करेगा यदि शर्त पूरी नहीं हुई है।
enable_ifकरने के लिए है कि चूक पैरामीटर एक दूसरे प्रकार लेता है void। अभिव्यक्ति enable_if< true, int >::typeप्रकार का प्रतिनिधित्व करती है int। मैं वास्तव में नहीं समझ सकता कि आपका पहला सवाल क्या है, आप जो भी चाहें, उसके लिए आप एसएफएनईईई का उपयोग कर सकते हैं, लेकिन मैं यह बिल्कुल नहीं समझता कि आप सभी कार्यों के साथ क्या करना चाहते हैं।
C ++ 11 के बाद से आपको Boost या की आवश्यकता नहीं है static_assert। C ++ 11 परिचय is_base_of और enable_if। C ++ 14 सुविधा प्रकार का परिचय देता है enable_if_t, लेकिन यदि आप C ++ 11 के साथ फंस गए हैं, तो आप enable_if::typeइसके बजाय बस उपयोग कर सकते हैं ।
डेविड रोड्रिग्स के समाधान को इस प्रकार फिर से लिखा जा सकता है:
#include <type_traits>
using namespace std;
template <typename T>
enable_if_t<is_base_of<Base, T>::value, void> function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
C ++ 17 के बाद से, हमारे पास है is_base_of_v। समाधान को आगे फिर से लिखा जा सकता है:
#include <type_traits>
using namespace std;
template <typename T>
enable_if_t<is_base_of_v<Base, T>, void> function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
तुम भी पूरे टेम्पलेट को प्रतिबंधित कर सकते हैं। आप पूरी कक्षाओं को परिभाषित करने के लिए इस पद्धति का उपयोग कर सकते हैं। ध्यान दें कि दूसरे पैरामीटर को कैसे enable_if_tहटा दिया गया है (यह पहले शून्य पर सेट किया गया था)। इसका डिफ़ॉल्ट मान वास्तव में है void, लेकिन इससे कोई फर्क नहीं पड़ता, क्योंकि हम इसका उपयोग नहीं कर रहे हैं।
#include <type_traits>
using namespace std;
template <typename T,
typename = enable_if_t<is_base_of_v<Base, T>>>
void function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
टेम्पलेट मापदंडों के प्रलेखन से, हम देखते हैं कि typename = enable_if_t...एक खाली नाम के साथ एक टेम्पलेट पैरामीटर है। हम केवल यह सुनिश्चित करने के लिए इसका उपयोग कर रहे हैं कि एक प्रकार की परिभाषा मौजूद है। विशेष रूप से, enable_if_tपरिभाषित नहीं किया जाएगा यदि Baseइसका आधार नहीं है T।
उपरोक्त तकनीक को उदाहरण के रूप में दिया गया है enable_if।
template <class T : Base>
आप इस्तेमाल कर सकते हैं बूस्ट संकल्पना चेक की BOOST_CONCEPT_REQUIRES:
#include <boost/concept_check.hpp>
#include <boost/concept/requires.hpp>
template <class T>
BOOST_CONCEPT_REQUIRES(
((boost::Convertible<T, BaseClass>)),
(void)) function()
{
//...
}
बेस क्लास में मौजूद आपके टेम्प्लेट के अंदर फ़ंक्शन को कॉल करके।
यदि आप अपने टेम्पलेट को उस प्रकार से आज़माते और त्वरित करते हैं जिसकी इस फ़ंक्शन तक पहुंच नहीं है, तो आपको एक संकलन-समय त्रुटि प्राप्त होगी।
T एक है BaseClass क्योंकि में घोषित सदस्यों BaseClassकी घोषणा में दोहराया जा सकता T।