2016-01-15 15 views
7

तो मैं this article about type erasure पढ़ रहा था। लेकिन उस लेख में कोड आंशिक रूप से गलत लगता है, उदाहरण के लिए:सी ++ में टाइप एरर क्या है?

template <typename T> 
class AnimalWrapper : public MyAnimal 
{ 
    const T &m_animal; 

public: 
    AnimalWrapper(const T &animal) 
     : m_animal(animal) 
    { } 

    const char *see() const { return m_animal.see(); } 
    const char *say() const { return m_animal.say(); } 
}; 

द्वारा

void pullTheString() 
{ 
    MyAnimal *animals[] = 
    { 
     new AnimalWrapper(Cow()), /* oO , isn't template argument missing? */ 
     .... 
    }; 
} 

पीछा इन गलतियों मुझे किसी भी लेख में आगे पढ़ने से हतोत्साहित किया।

वैसे भी; क्या कोई भी सिखा सकता है कि सरल उदाहरणों के साथ सी ++ में किस तरह का मिटाना है?

मैं यह समझने के लिए जानना चाहता था कि कैसे std::function काम करता है, लेकिन मेरे सिर को इसके आसपास नहीं मिल सका।

+0

संबंधित/शिकार: http://stackoverflow.com/questions/5450159/type-erasure-techniques – NathanOliver

+1

आप या तो '' गुजरती हैं, या उपयोग करने के लिए एक समारोह है कि 'deduces T' और' ' गुजरता है की जरूरत है। हां, 'टेम्पलेट माईएनिमल * रैपएनिमल (टी कॉन्स्ट एंड टी) {नया AnimalWrapper (टी);} ', और' व्रपएनिमल 'के साथ' नया AnimalWrapper 'को प्रतिस्थापित करें। – Yakk

+0

@NathanOliver उस प्रश्न में ओपी पहले से ही टाइप एरर की बुनियादी अवधारणाओं को जानता है। –

उत्तर

10

यहाँ कार्रवाई में प्रकार विलोपन की एक बहुत ही सरल उदाहरण है:

// Type erasure side of things 

class TypeErasedHolder 
{ 
    struct TypeKeeperBase 
    { 
    virtual ~TypeKeeperBase() {} 
    }; 

    template <class ErasedType> 
    struct TypeKeeper : TypeKeeperBase 
    { 
    ErasedType storedObject; 

    TypeKeeper(ErasedType&& object) : storedObject(std::move(object)) {} 
    }; 

    std::unique_ptr<TypeKeeperBase> held; 

public: 
    template <class ErasedType> 
    TypeErasedHolder(ErasedType objectToStore) : held(new TypeKeeper<ErasedType>(std::move(objectToStore))) 
    {} 
}; 

// Client code side of things 

struct A 
{ 
    ~A() { std::cout << "Destroyed an A\n"; } 
}; 

struct B 
{ 
    ~B() { std::cout << "Destroyed a B\n"; } 
}; 

int main() 
{ 
    TypeErasedHolder holders[] = { A(), A(), B(), A() }; 
} 

[Live example]

आप देख सकते हैं, TypeErasedHolder एक मनमाना प्रकार की वस्तुओं स्टोर कर सकते हैं, और उन्हें सही ढंग से संहार। महत्वपूर्ण बात यह है कि यह (1) समर्थित प्रकारों पर किसी भी प्रतिबंध को लागू नहीं करता है: उदाहरण के लिए, उन्हें सामान्य आधार से प्राप्त नहीं करना है।


(1) चल जा रहा है, निश्चित रूप से के अलावा।

+0

एचएम, आप 'टाइपरिपरहोल्डर' और ''std :: forward'' के कन्स्ट्रक्टर तर्क के लिए' '&&' '(सार्वभौमिक संदर्भ (?)) का उपयोग क्यों नहीं कर रहे हैं, इसे 'टाइपकीपर' पर पास करने के लिए '? (यहां समझने की कोशिश कर रहा है, ऐसा लगता है कि आप हमेशा एक प्रतिलिपि ले रहे हैं और फिर मूल वस्तु को स्थानांतरित करने के बजाय उस प्रतिलिपि से आगे बढ़ रहे हैं) –

+1

@ जोनासविएलिकी उदाहरण के "बहुत सरल" पहलू को रखने के लिए। फॉरवर्डिंग संदर्भ का उपयोग करने के लिए 'टाइपकीपर' इत्यादि के लिए टेम्पलेट तर्क के लिए 'std :: remove_reference' का उपयोग करने की आवश्यकता होगी। – Angew

+0

स्पष्टीकरण के लिए धन्यवाद! –

संबंधित मुद्दे