2012-09-19 18 views
6

प्राप्त करें मैं प्रतिबिंब डेटा से वस्तुओं को बनाने के लिए ऑब्जेक्ट निर्माण के लिए टेम्पलेट फ़ंक्शंस का उपयोग कर रहा हूं, और यह बहुत अच्छी तरह से काम करता है, लेकिन अब मैं प्रतिबिंब प्रणाली में एसटीएल कंटेनर प्रकारों का समर्थन करना चाहता हूं ताकिसी ++ वेक्टर प्रकार

// Note - test case only 
// for real world usage it would probably not be structured like this 
// and the phrases would be mapped by an id or something 
struct Phrases { 
    std::vector<std::string> phrases; 
}; 

typedef std::string Lang; 
struct Langs { 
    std::map< Lang, Phrases > translations; 
}; 

समर्थित किया जा सकता है। मैं यह पता लगाने की अगर एक वस्तु एक वेक्टर या एक नक्शा है, और क्या वस्तु के लिए पैरामीटर तर्क है

typeid(object).name() 

की वापसी पर कुछ regex जादू कर सकते हैं। और मैंने कुछ टेम्पलेट जादू को निम्नलिखित की तरह कुछ करने की कोशिश की है, जहां CreateString, ConstructString & DestroyString फ़ंक्शंस में खड़े हैं और डेटा कुछ और जटिल के लिए भी खड़ा है जो ऑब्जेक्ट निर्माण को संभालने के लिए किसी प्रकार डेटाबेस का उपयोग करता है।

// Representational of code, basically a copy-paste to a different test project where I can work out the problems with this specific vector problem 
// Vector specialised construction 
template <typename T> void ConstructVector(void* object, const std::vector<std::string>& data) { 
    T* vec = (T*)object; 
    Name vector_type = GetVectorTypeName<T>(); 

    void *obj; 
    CreateString(&obj); 
    // All fields in this type should be valid objects for this vector 
    for(std::vector<std::string>::const_iterator it = data.begin(), end = data.end(); it != end; ++it) { 
    // Push it 
    vec->push_back(*obj); 
    // Get address to new instance 
    void *newly = &vec->back(); 
    ConstructString(newly,*it); 
    } 
    DestroyString(&obj); 

} 

कौन सा के साथ अवैध अविवेक के कारण काम नहीं करता है "vec-> push_back (* obj)," जो मैं मामला नहीं कर सकता क्योंकि मुझे वास्तव में इस प्रकार का पता नहीं है। असल में मुझे ऐसा करने में सक्षम होना चाहिए कि इस वेक्टर को पहले से ही कुछ खाली असंतुलित तत्वों के साथ बनाएं, या वास्तव में टाइप किए बिना इसमें नए तत्व जोड़ें, क्योंकि अगर मैं वेक्टर के अंदर मेमोरी ब्लॉक में पॉइंटर प्राप्त कर सकता हूं उस के साथ रोल और वस्तु का निर्माण। लेकिन वेक्टर के रूप में

vector::push_back(T& value) 

या

ऐसी जरूरतों जोड़ने
vector::insert(Iter&, T&) 

जब तक कि मैं टेम्पलेट परीक्षण कोड की

pastebin अंदर से कि टी प्रकार पर मेरे हाथ प्राप्त कर सकते हैं मेरे लिए काम नहीं करेंगे इसे हल करने और हल करने के लिए: http://pastebin.com/1ZAw1VXg

तो मेरा सवाल यह है कि, मैं std :: वेक्टर घोषणा के std :: स्ट्रिंग भाग को कैसे प्राप्त कर सकता हूं जब मैं

template <typename T> void SomeFunc() { 

    // Need to get std::string here somehow  
    // Alternatively need to make the vector a certain size and then 
    // get pointers to it's members so I can construct them 
} 


SomeFunc<std::vector<std::string>>>(); 
+1

'std :: vector':

template <typename Elem> using myvector = std::vector<Elem>; 

तो मैं इस तरह SomeFunc उपयोग कर सकते हैं: एक बात है कि मेरे लिए काम किया वेक्टर प्रकार के उपनाम है कि केवल एक टेम्पलेट पैरामीटर छोड़ देता है की घोषणा करने के लिए है यदि आपको वही चाहिए तो एक आंतरिक 'typedef टी value_type' है। –

उत्तर

15

जैसे टेम्पलेट के अंदर हूं, इसे पूरा करने के दो तरीके हैं।

1) या तो आप तथ्य यह है कि std::vector<> (सभी मानक पुस्तकालय कंटेनर क्लासों की तरह) एक सदस्य प्रकार value_type, जो वेक्टर में संग्रहीत तत्वों के प्रकार का प्रतिनिधित्व करता है का कहना है का उपयोग करें। तो अगर आप ऐसा कर सकते हैं:

template <typename T> void SomeFunc() { 
    typename T::value_type s; // <--- declares a `std::string` object 
          //  if `T` is a `std::vector<std::string>` 
} 

2) वरना, आप अपने समारोह की घोषणा बदल सकते हैं और टेम्पलेट टेम्पलेट मापदंडों का इस्तेमाल करते हैं:

template <template <typename> class T, typename Elem> 
void SomeFunc(T<Elem> &arg) 
{ 
    Elem s; 
} 

हालांकि, वहाँ के साथ एक छोटी सी समस्या है कि: std::vector वास्तव में दो पैरामीटर (तत्व प्रकार और आवंटक प्रकार) के साथ एक टेम्पलेट है, जो टेम्पलेट टेम्पलेट पैरामीटर का उपयोग करना थोड़ा मुश्किल बनाता है और अभी भी सिंटैक्स को सरल रखता है।

int main() 
{ 
    myvec<std::string> vec; 
    SomeFunc(vec); 
} 
+0

इसके लिए धन्यवाद, यह मुझे हल किए गए समाधान के मुकाबले फ़ंक्शन का एक अधिक क्लीनर संस्करण बनाने की अनुमति देगा। – kyall

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