वर्चुअल सदस्य कार्यों के ओवरहेड से बचने के लिए मैं C ++ में CRTP का उपयोग कैसे कर सकता हूं?
वर्चुअल सदस्य कार्यों के ओवरहेड से बचने के लिए मैं C ++ में CRTP का उपयोग कैसे कर सकता हूं?
जवाबों:
इसके दो तरीके हैं।
पहला एक प्रकार की संरचना के लिए इंटरफ़ेस को निर्दिष्ट करके है:
template <class Derived>
struct base {
void foo() {
static_cast<Derived *>(this)->foo();
};
};
struct my_type : base<my_type> {
void foo(); // required to compile.
};
struct your_type : base<your_type> {
void foo(); // required to compile.
};
दूसरा एक संदर्भ-से-आधार या पॉइंटर-टू-बेस मुहावरे के उपयोग से बचने और संकलन-समय पर वायरिंग करने के लिए है। उपरोक्त परिभाषा का उपयोग करते हुए, आपके पास इस तरह दिखने वाले टेम्प्लेट फ़ंक्शंस हो सकते हैं:
template <class T> // T is deduced at compile-time
void bar(base<T> & obj) {
obj.foo(); // will do static dispatch
}
struct not_derived_from_base { }; // notice, not derived from base
// ...
my_type my_instance;
your_type your_instance;
not_derived_from_base invalid_instance;
bar(my_instance); // will call my_instance.foo()
bar(your_instance); // will call your_instance.foo()
bar(invalid_instance); // compile error, cannot deduce correct overload
इसलिए संरचना / इंटरफ़ेस की परिभाषा और आपके कार्यों में संकलन-समय प्रकार की कटौती आपको गतिशील प्रेषण के बजाय स्थिर प्रेषण करने की अनुमति देती है। यह स्थैतिक बहुरूपता का सार है।
not_derived_from_base
यह व्युत्पन्न नहीं है base
, और न ही यह व्युत्पन्न है base
...
मैं खुद CRTP की अच्छी चर्चा कर रहा हूँ। टॉड वेल्डहुइज़न की तकनीक फॉर साइंटिफिक C ++ इसके लिए एक बेहतरीन संसाधन (1.3) और कई अन्य उन्नत तकनीकों जैसे एक्सप्रेशन टेम्प्लेट हैं।
इसके अलावा, मैंने पाया कि आप Google पुस्तकों में अधिकांश कोप्लिन के मूल C ++ रत्न लेख को पढ़ सकते हैं। शायद अभी भी यही है।
dynamic_cast
या आभासी तरीकों की आवश्यकता होगी ।
मुझे CRTP देखना था । हालांकि, ऐसा करने पर मुझे स्टैटिक पॉलीमॉर्फिज़्म के बारे में कुछ चीजें मिलीं । मुझे संदेह है कि यह आपके प्रश्न का उत्तर है।
यह पता चला है कि एटीएल इस पैटर्न का काफी उपयोग करता है।
इस विकिपीडिया उत्तर की आपको सभी आवश्यकता है। अर्थात्:
template <class Derived> struct Base
{
void interface()
{
// ...
static_cast<Derived*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
Derived::static_sub_func();
// ...
}
};
struct Derived : Base<Derived>
{
void implementation();
static void static_sub_func();
};
हालांकि मुझे नहीं पता कि यह वास्तव में आपको कितना खरीदता है। वर्चुअल फ़ंक्शन कॉल का ओवरहेड (कंपाइलर निर्भर, निश्चित रूप से) है:
जबकि CRTP स्थैतिक बहुरूपता का उपरी भाग है: