2009-12-31 12 views
5

के लिए प्रकार निर्धारित करता है, मुझे आश्चर्य है कि टाइप को C++ में रनटाइम जानकारी के रूप में निर्धारित किया जा सकता है या नहीं।रनटाइम सी ++

(1) हालांकि मेरे सवाल का काफी सामान्य है, सादगी के लिए, मैं एक साधारण उदाहरण से शुरू कर देंगे:

(क) "argv:

#include <stdio.h> 
#include <iostream> 
#include <cstring> 
using namespace std; 
int main(int argc, char * argv[]) 
{ 
if (strcmp(argv[1], "int")==0) 
{ 
    int t = 2; 
}else if (strcmp(argv[1], "float")==0) 
{ 
    float t = 2.2; 
} 
cout << t << endl; // error: ‘t’ was not declared in this scope 
return 0; 
} 

इस उदाहरण के लिए, वहाँ दो सवाल कर रहे हैं [1] से टी "गलत है, लेकिन सी स्ट्रिंग argv [1] में टाइप जानकारी वास्तविक प्रकार के कीवर्ड में परिवर्तित हो सकती है? इसलिए हमें हर प्रकार की जांच करने की आवश्यकता नहीं है-और खंड और strcmp।

(बी) यदि खंड अभी भी वैध है तो स्थानीय दायरे के अंदर परिभाषित चर टी को कैसे बनाया जाए। यानी एक स्थानीय चर को अपने दायरे के बाहर "निर्यात" कैसे करें?

(2) आम तौर पर ऊपर दिए गए सरल उदाहरण के लिए विशिष्ट नहीं, रनटाइम प्रकारों को निर्धारित करने के सामान्य तरीके क्या हैं? ऐसा लगता है कि कुछ तरीके हो सकते हैं:

(ए) कोई भी अपनी परिभाषा के उसी दायरे के अंदर टाइप किए गए चर के प्रोसेसिंग को प्रोसेस कर सकता है। जैसे

#include <stdio.h> 
#include <iostream> 
#include <cstring> 
using namespace std; 
int main(int argc, char * argv[]) 
{ 
if (strcmp(argv[1], "int")==0) 
{ 
    int t = 2; 
    cout << t << endl; 
}else if (strcmp(argv[1], "float")==0) 
{ 
    float t = 2.2; 
    cout << t << endl; 
} 
return 0; 
} 

और संभावित रूप से विभिन्न प्रकार के पुन: प्रयोज्य के लिए सामान्य कोड बनाने के लिए टेम्पलेट फ़ंक्शन का उपयोग करें।

(बी) या कोई अप्रत्यक्ष रूप से परिभाषा को निर्यात करने के लिए अमूर्त वर्ग प्रकार और बहुरूपता का उपयोग कर सकता है, लेकिन मुझे यकीन नहीं है कि वास्तव में कैसे।

आपकी सलाह के लिए धन्यवाद!

उत्तर

7

1 ए: नहीं, प्रकार सी ++ में ऑब्जेक्ट्स या मान नहीं हैं (जैसा कि वे हैं, उदाहरण के लिए, पायथन में)। हालांकि, आप argv [1] के मान द्वारा चुने गए विभिन्न मानों का उपयोग कर सकते हैं।

1b: क्षमा करें, बस ऐसा नहीं कर सकता।

2: गतिशील_कास्ट और टाइपिड (दोनों ऑपरेटरों) वर्तमान में भाषा प्रकार से पूछे जाने वाले एकमात्र उपकरण हैं (असामान्य नहीं, अधिकांश भाषाओं में बहुत कम हैं, लेकिन समर्पित हैं, इसके लिए उपकरण), और उन्हें पूरी तरह से क्वेरी प्रकार के लिए उपयोग करना अक्सर स्थिति के आधार पर निराश होता है (अन्य भाषाओं के बीच भी असामान्य नहीं)।

2 ए: हाँ, और यह सरल, स्पष्ट, और यहां काम करता है — किसी और चीज का उपयोग करने का कोई कारण नहीं है, लेकिन जैसा कि यह उदाहरण कोड है, मान लीजिए कि आपको एक अलग समाधान की आवश्यकता है। आप सही प्रकार पर तत्काल एक फ़ंक्शन टेम्पलेट को कॉल कर सकते हैं, लेकिन जैसा कि यह 2a शेष के समान ही है, मैं इसमें नहीं जाता हूं।

2 बी: उदाहरण एक उपवर्ग टेम्पलेट का उपयोग कर, सिर्फ इसलिए कि यह आसान है:

struct Base { 
    virtual ~Base() {} 
    friend std::ostream& operator<<(std::ostream& s, Base const& v) { 
    v._print(s); 
    return s; 
    } 
private: 
    virtual void _print(std::ostream&) const = 0; 
}; 

template<class T> 
struct Value : Base { 
    T data; 
    explicit 
    Value(T const& data) : data(data) {} 
private: 
    virtual void _print(std::ostream& s) const { 
    s << data; 
    } 
}; 

उपयोग:

int main(int argc, char** argv) { 
    using namespace std; 
    auto_ptr<Base> p; 
    string const type = argc > 1 ? argv[1] : "int"; 
    if (type == "int") { 
    p.reset(new Value<int>(2)); 
    } 
    else if (type == "float") { 
    p.reset(new Value<double>(2.2)); 
    } 
    cout << *p << '\n'; 
    return 0; 
} 

यह एक प्रकार में दो प्रकार के विलय करने के लिए शुरू कर रहा है, और वे दोनों पेश एक ही इंटरफेस, बेस, यहाँ।हालांकि, यह हर समाधान के लिए खुद को अच्छी तरह से उधार नहीं देता है, और boost.variant जैसे एक संस्करण बेहतर हो सकता है, खासकर जब आवश्यक विभिन्न प्रकार संख्या में छोटे होते हैं और पहले से ही ज्ञात होते हैं।

+0

+1 मैं पॉलिमॉर्फिक समाधान पोस्ट करने जा रहा था। Boost.variant की तुलना में अधिक समझ में आता है क्योंकि boost.variant के साथ आपको प्रत्येक ऑपरेशन के लिए प्रकार की जांच करने की आवश्यकता होगी। –

5

आपको एक कक्षा की आवश्यकता है जो विभिन्न प्रकारों के मूल्य को संग्रहीत करने में सक्षम है। एक संघ से कम, Boost's variant class उचित विकल्प होगा।

+0

यदि बूस्ट का उपयोग नहीं किया जा रहा है? – Tim

+0

जैसा कि मैंने उल्लेख किया है, एक संघ। –

2

Boost.Variant देखें।

+1

मूल प्रश्न में कुछ भी बूस्ट के उपयोग का सुझाव नहीं देता है। एक समारोह के लिए उसे एक नया फ्रेम फ्रेम क्यों शामिल करना चाहिए? मुझे खेद है, लेकिन मैं इसे सहायक होने के रूप में नहीं देखता हूं। –

+3

@druciferre: प्रश्न पूछता है कि सी ++ में कुछ कैसे करें। हालांकि कई अनुभवी सी ++ डेवलपर्स ने बढ़ावा देने के बारे में नहीं सुना होगा, उनके पास होना चाहिए। प्रश्न में पहले से ही नामस्थान एसडीडी, मानक टेम्पलेट लाइब्रेरी के संदर्भ शामिल हैं, और आप बूस्ट को एसटीएल के रूप में उपयोग के लिए व्यवहार्य मान सकते हैं। अब बूस्ट के भीतर बहुत सारी पुस्तकालय हैं, इसलिए केवल कुछ ही किसी दिए गए समस्या के लिए सार्थक हो रहे हैं। – jmc