2009-11-14 16 views
6

क्या रनटाइम पर जेनेरिक प्रकार का क्लास चुनने का कोई तरीका है या यह सी ++ में संकलन-समय की बात है?क्या रनटाइम पर C++ सामान्य प्रकार पैरामीटर चुनना संभव है?

इस (स्यूडोकोड) की तरह कुछ मुझे क्या करना चाहते हैं:

Generictype type; 
if(somveval==1) 
    type = Integer; 
if(someval==2) 
    type = String; 

list<type> myList; 

सी ++ में यह संभव है? और यदि हां, तो कैसे?

+2

कुछ भी संभव है। लेकिन आप जो करने की कोशिश कर रहे हैं वह सी ++ में आसान नहीं है। यदि आप समझते हैं कि आप ऐसा करने का प्रयास क्यों कर रहे हैं तो हम आपको बेहतर सलाह दे सकते हैं। –

उत्तर

10

यह एक संकलित समय की बात है। टेम्पलेट पैरामीटर प्रकार संकलन समय पर संकलक के लिए जाना जाना चाहिए।

कुछ टेम्पलेट मेटा-प्रोग्रामिंग तकनीकों का उपयोग करके कहा जा रहा है कि आप एक प्रकार या अन्य एटी संकलन-समय चुन सकते हैं, लेकिन केवल तभी जब सभी संभव प्रकार संकलित समय पर ज्ञात हैं, और केवल तभी प्रकार संकलन समय पर हल किया जा सकता है।

उदाहरण के लिए

, आंशिक विशेषज्ञता का उपयोग कर आप एक पूर्णांक के आधार पर, संकलन समय पर प्रकार का चयन कर सकते हैं:

template <typename T> 
class Foo 
{ }; 

template <int N> 
struct select_type; 

template<> 
struct select_type<1> 
{ 
    typedef int type; 
}; 

template<> 
struct select_type<2> 
{ 
    typedef float type; 
}; 

int main() 
{ 
    Foo<select_type<1>::type> f1; // will give you Foo<int> 
    Foo<select_type<2>::type> f2; // will give you Foo<float> 
} 
0

मैं एक स्थिति है जहाँ यह उपयोगी होगा के बारे में सोच नहीं सकता है, लेकिन है & hellip;

#include "boost/variant.hpp" 
#include <list> 
#include <string> 

boost::variant<std::list<int>, std::list<std::string> > 
unknown(int someval) { 
    if (someval == 1) 
     return boost::variant<std::list<int>, std::list<std::string> >(
       std::list<int>()); 
    else if (someval == 2) 
     return boost::variant<std::list<int>, std::list<std::string> >(
       std::list<std::string>()); 
} 
1

के रूप में दूसरों को भी प्रतिक्रिया व्यक्त की है, अपने प्रश्न का उत्तर "नहीं", सी ++ रन-टाइम में गतिशील टाइपिंग का समर्थन नहीं करता है। मैं बस यह इंगित करना चाहता था कि आप जो हासिल करने की कोशिश कर रहे हैं उसके आधार पर, आप को यूनियन का उपयोग करके इस गतिशील टाइपिंग को अनुकरण कर सकते हैं, इस प्रकार COM12 में VARIANT type लागू किया गया है।

0

निकटतम आप मिल जाएगा है:

template <typename T> 
void do_stuff_with_list 
{ 
    list<T> myList; 
    ... 
} 

enum Type 
{ 
    Integer = 1, 
    String 
}; 

void do_stuff(Type type) 
{ 
    switch (type) 
    { 
    case Integer: 
     do_stuff_with_list<int>(); 
     break; 
    case String: 
     do_stuff_with_list<string>(); 
     break; 
    }; 
} 
2

यह Boost.Variant (विभिन्न प्रकार के निश्चित संख्या) या Boost.Any (एक प्रकार है कि किसी भी प्रकार के स्टोर कर सकते हैं, मूल रूप से अपने "शून्य के साथ संभव है सूचक "लेकिन प्रकार की जानकारी के साथ)।

स्ट्रिंग और इंटीजर को पॉलिमॉर्फिक बेस क्लास से प्राप्त किया जाना भी संभव है। (लेकिन इसके लिए उन्हें एक ही इंटरफेस को लागू करना होगा, जो आपके मामले में संभव हो सकता है या नहीं।)

आम तौर पर, बहुरूपता इसे करने का सबसे आसान तरीका है, और यह वास्तव में हर समय उपयोग किया जाता है।

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

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