आम तौर पर यह प्रतिबंधित करने के लिए अनावश्यक है कि किस प्रकार के टेम्पलेट्स को तुरंत चालू किया जा सकता है। या तो टेम्पलेट दिए गए प्रकार (और ठीक काम करता है) के साथ संकलित है या यह नहीं है (और प्रोग्रामर के हिस्से पर किसी भी प्रयास के बिना एक कंपाइलर त्रुटि उत्पन्न करता है)।
आप प्रतिबंध में डालने के लिए की जरूरत है, आम तौर पर प्रकार आम में कुछ कुछ प्रकार के लक्षण है कि पहले से ही उपलब्ध हैं (मानक पुस्तकालय, boost::type_traits
) द्वारा वर्णित किया जा सकता है कि है, या आप के लिए एक नए प्रकार विशेषता बना सकते हैं उन्हें।
उदाहरण के लिए, यहां एक टेम्पलेट क्लास है जो इसे देखने के लिए std::numeric_limits
का उपयोग करके पूर्णांक प्रकारों की अनुमति देता है (यदि आप अपना स्वयं का अंकीय प्रकार लिखते हैं, तो आप इसे विशेषज्ञ कर सकते हैं ताकि यह आपके नए पूर्णांक प्रकार के साथ भी काम करे)। static_assert
केवल सी ++ 0x है, अगर उपलब्ध नहीं है तो BOOST_STATIC_ASSERT
या कुछ अन्य चाल का उपयोग करें।
#include <limits>
#include <string>
template <class T>
class X
{
static_assert(std::numeric_limits<T>::is_integer, "X can be only instantiated with integer types");
//...
};
int main()
{
X<int> xi;
X<char> xc;
//X<double> xd;
//X<std::string> xs;
}
आप केवल आम में कुछ भी नहीं के साथ मनमाना प्रकार के एक मुट्ठी भर का समर्थन करने के (के रूप में अपने काल्पनिक उदाहरण से स्पष्ट है) की योजना है, एक तरह से typelists को रोजगार के लिए है। फिर से बढ़ावा देने से कार्य बहुत आसान हो सकता है, लेकिन यहां बताया गया है कि आप अपना खुद का रोल कैसे कर सकते हैं (यह केवल आधा रास्ता जाता है, टाइपलिस्टिस्ट सुंदर को घोषित करने के लिए अतिरिक्त काम की आवश्यकता होगी)।
struct no_type {};
template <class T, class U = no_type>
struct t_list
{
typedef T head;
typedef U tail;
};
//trait to check if two types are identical
template <class T, class U>
struct is_same
{
static const bool value = false;
};
template <class T>
struct is_same<T, T>
{
static const bool value = true;
};
//compile-time recursion to check if T matches any type in list L
template <class T, class L>
struct in_type_list
{
static const bool value =
is_same<T, typename L::head>::value || in_type_list<T, typename L::tail>::value;
};
//terminates recursion
template <class T>
struct in_type_list<T, no_type>
{
static const bool value = false;
};
template <class T>
class X
{
typedef t_list<double, t_list<int, t_list<char> > > allowed_types; //double, int, char
//poor man's static_assert
typedef int check_type [in_type_list<T, allowed_types>::value ? 1 : -1];
//...
};
int main()
{
X<char> xc;
X<int> xi;
X<double> xd;
//X<float> xf;
}
मैं उत्सुक हूँ के लिए अपरिभाषित छोड़ने के लिए है, जो उपयोग के मामले आप अपने टेम्पलेट के कुछ इन्स्टेन्शियशन मना के लिए क्या है? मैं यह नहीं समझ सकता कि मैं अपने कोड का पुन: उपयोग क्यों नहीं करना चाहूंगा: -/ – Seb
"भिन्न हो सकता है" का क्या अर्थ है? क्या वे संकलन समय में भिन्न हो सकते हैं या उदाहरण के मुकाबले अलग हो सकते हैं? – foraidt
@ सेब: टेम्पलेट कुछ प्रकार के साथ सही ढंग से काम नहीं कर सकता है। यह संकलित नहीं हो सकता है (जिस स्थिति में कंपाइलर जो कुछ भी उत्पन्न करता है उससे क्लीनर त्रुटि संदेश वांछनीय हो सकता है), या यह संकलित हो सकता है लेकिन वांछित अर्थशास्त्र नहीं है (जिस स्थिति में इसे संकलन से रोकने के लिए एक तरीका अच्छा है) – jalf