मुझे चर का प्रकार कैसे मिलेगा?


130

C ++ में, एक चर का प्रकार कैसे पता चलता है?


5
के संभावित डुप्लिकेट stackoverflow.com/questions/81870/print-variable-type-in-c
theharshest

7
cout << टाइपिड (परिवर्तनशील) .name () << endl;
SRN

2
खोज या Google का उपयोग करें :) stackoverflow.com/questions/81870/print-variable-type-in-c Theharshest तेज है: D
Kariboo

14
@ कारिबू, मैंने Google का उपयोग किया और इसने मुझे यहां भेजा।
माइकल वार्नर

यह प्रश्न बहुत अस्पष्ट है क्योंकि यह है, और विभिन्न उत्तरों को देखने के बाद भी; यह किसी भी तरह से स्पष्ट नहीं है कि प्रश्न स्वीकृत उत्तर की मांग कर रहा है।
एंटटी हापाला

जवाबों:


158

आप टाइपिड ऑपरेटर का उपयोग कर सकते हैं :

#include <typeinfo>
...
cout << typeid(variable).name() << endl;

15
@ डेविड - तो iअपने संकलक पर पूर्णांक का मतलब है। लौटाए गए नाम मानक द्वारा निर्दिष्ट नहीं हैं।
बो पर्सन

11
जब मैं इसे वेक्टर <int> पर उपयोग करता हूं तो यह St6vectorIiSaIiEE देता है। WTF?
बॉयन कुशलेव

2
@Bobby तुम अकेले नहीं हो !! google.co.uk/webhp#safe=off&q=St6vectorIiSaIiEE
रिच ओ'केली

5
द्वारा लौटाए गए नाम typeidबहुत संक्षिप्त, संकलक-विशिष्ट हैं, और मानव उपभोग के लिए अभिप्रेत नहीं हैं। आप कर सकते हैं "demangle" उन्हें (कि वास्तविक अवधि है!), या तो की तरह कुछ के साथ कोड में gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , जैसे कमांड लाइन उपयोगिताओं के साथ c++filt, या विभिन्न ऑनलाइन demanglers से किसी के साथ जैसे कि demangler.com
सिनकोडेनदा

33

स्थैतिक अभिकथन के लिए, C ++ 11 पेश किया गया decltypeजो कुछ परिदृश्यों में काफी उपयोगी है।


12

यदि आपके पास एक चर है

int k;

आप इसके प्रकार का उपयोग कर प्राप्त कर सकते हैं

cout << typeid(k).name() << endl;

एसओ पर निम्नलिखित सूत्र देखें: इसी तरह का प्रश्न


9

C ++ और जावास्क्रिप्ट के बीच मुख्य अंतर यह है कि C ++ एक स्थिर-टाइप की गई भाषा है, wile जावास्क्रिप्ट डायनामिक है।

डायनेमिक टाइप की गई भाषाओं में एक चर में जो भी चीज हो सकती है, और उसका प्रकार इसके मूल्य द्वारा दिया जाता है, पल-पल। स्थिर टाइप की गई भाषाओं में एक चर का प्रकार घोषित किया जाता है, और इसे बदल नहीं सकते।

डायनेमिक डिस्पैच और ऑब्जेक्ट कंपोजिशन और सबटाइपिंग (इनहेरिटेंस और वर्चुअल फंक्शन्स) के साथ-साथ स्टैटिक-डिस्पैच और सुपरटेपिंग (टेम्प्लेट CRTP के जरिए) हो सकता है, लेकिन किसी भी स्थिति में कंपाइलर को वेरिएबल का प्रकार पता होना चाहिए।

यदि आप यह जानने की स्थिति में नहीं हैं कि यह क्या है या हो सकता है, तो यह इसलिए है क्योंकि आपने कुछ डिज़ाइन किया है क्योंकि भाषा में एक गतिशील प्रकार-प्रणाली है।

अगर ऐसा है तो आप अपने डिजाइन पर फिर से विचार कर सकते हैं, क्योंकि यह आपके द्वारा उपयोग की जा रही भाषा के लिए स्वाभाविक नहीं है (जैसे कि कैटरपिलर के साथ मोटरवे में जाना पसंद है, या कार के साथ पानी में)


अगर C ++ में डायनेमिक चेंजिंग है तो मुझे लगता है कि यह बहुत बढ़िया और टाइपो और parseInt होगा, parseFloat फंक्शन भी काम आएंगे, लेकिन मुझे नहीं पता कि C ++ मेकर्स इसे कितना कठिन बनाते हैं, उदाहरण के लिए! जो इसे लिखने के लिए अच्छा कहता है << "स्ट्रिंग"
वकास ताहिर

दृढ़ संकल्प सबसे अच्छा है !!!! #include <sstream> string str ("1912"); इंट स्ट्रेटनॉवल; stringstream (str) >> strtointval;
वकास ताहिर

@ अकास उह, क्या? जो लोग कहते हैं कि यह सबसे अच्छा है वे लोग हैं जो भाषा को परिभाषित करते हैं, और आईएमओ के पास इसके साथ कुछ भी करने के लिए अंतिम बहुत कुछ है - उदाहरण के लिए अच्छा कोडिंग अभ्यास। क्या आप उस टिप्पणी को पुनः प्राप्त कर सकते हैं जिससे यह अधिक समझ में आता है?
निधि मोनिका का मुकदमा

मैं पूरी तरह से असहमत हूँ। जावा, सी #, पीएचपी, पर्ल, पायथन और इतने पर सी और सी ++ में डिजाइन किए गए थे और वे कैटरपिलर नहीं हैं। (जब आप 'अज्ञात' डेटाबेस से वैरिएबल टेबल खोलने के लिए एक डेटाबेस एप्लिकेशन बनाते हैं, तो आपको फ़ील्ड प्रकार को वैरिएबल स्कीम पर नियंत्रित करने की आवश्यकता होती है और 'बहुत' डायनामिक तरीके से वाइस;))
TomeeNS

@TomeeNS: नहींं। वे सी और सी ++ में लिखे गए हैं , डिज़ाइन नहीं किए गए हैं । वे अपने काम करने के लिए डिज़ाइन किए गए हैं। उनके पास गतिशील प्रकार हैं भले ही सी और सी ++ खुद न हों। यह अजीब बात नहीं है।
एमिलियो गरवाग्लिया

8

आमतौर पर, C ++ में वैरिएबल के प्रकार को ढूंढना गलत प्रश्न है। यह कुछ ऐसी चीज़ों की ओर ले जाता है जिन्हें आप प्रक्रियात्मक भाषाओं जैसे उदाहरण C या पास्कल से ले जाते हैं।

यदि आप प्रकार के आधार पर विभिन्न व्यवहारों को कोड करना चाहते हैं, तो उदाहरण के लिए फ़ंक्शन ओवरलोडिंग और ऑब्जेक्ट इनहेरिटेंस के बारे में जानने का प्रयास करें । यह आपके C ++ के पहले दिन पर तत्काल समझ में नहीं आएगा, लेकिन इसे बनाए रखें।


वास्तव में नहीं, मान लीजिए कि आपके पास एक क्लास ऑब्जेक्ट और एक उपवर्ग बुक है। अब कल्पना करें कि आपके पास एक बॉक्स है जो बहुत सारी वस्तुओं को संग्रहीत कर सकता है, लेकिन किसी कारण से आप इसके अंदर सभी पुस्तकों को सूचीबद्ध करना चाहते हैं। प्रकार की जाँच करना बहुत साफ है, फिर ऑब्जेक्ट में एक विधि "प्रकार" जोड़ना और फिर उसे बुक "
पाउलो सेसर

किसी भी नियम के रूप में, अपवाद हैं (इसलिए मेरे 'आमतौर पर'!), और कंटेनर प्रकार सिद्धांत में जटिलता जोड़ते हैं। मैं कभी भी कंटेनर-ऑफ-पॉलीमॉर्फ़िक-ऑब्जेक्ट्स से अधिक नहीं रहा हूं ... ज्यादातर मामलों में, टेम्पर्ड यूनिफॉर्म कंटेनर प्रकार पर्याप्त हैं और बहुत क्लीनर हैं।
पोंटस गैगे

क्या आप टेम्पलेट का उपयोग नहीं करते हैं?
ब्रायन ग्रेस

6

मेरा मानना ​​है कि मेरे पास टाइपिड () का उपयोग करने के लिए एक वैध उपयोग का मामला है, उसी तरह यह साइज़ोफ़ () का उपयोग करने के लिए वैध है। टेम्प्लेट फ़ंक्शन के लिए, मुझे टेम्प्लेट चर के आधार पर कोड को विशेष स्थिति में रखने की आवश्यकता है, ताकि मैं अधिकतम कार्यक्षमता और लचीलापन प्रदान कर सकूं।

यह बहुरूपता का उपयोग करने की तुलना में बहुत अधिक कॉम्पैक्ट और बनाए रखने योग्य है, प्रत्येक प्रकार के समर्थित फ़ंक्शन के लिए एक उदाहरण बनाने के लिए। उस स्थिति में भी मैं इस ट्रिक का उपयोग केवल एक बार फ़ंक्शन के शरीर को लिखने के लिए कर सकता हूं:

ध्यान दें कि क्योंकि कोड टेम्प्लेट का उपयोग करता है, इसलिए नीचे दिए गए स्विच स्टेटमेंट को केवल एक कोड ब्लॉक में हल करना चाहिए, जो सभी झूठे मामलों को दूर कर एएफएआईआईके को अनुकूलित करता है।

इस उदाहरण पर विचार करें, जहाँ हमें एक रूपांतरण को संभालने की आवश्यकता हो सकती है यदि T एक प्रकार बनाम दूसरा है। मैं हार्डवेयर तक पहुंचने के लिए वर्ग विशेषज्ञता के लिए इसका उपयोग करता हूं जहां हार्डवेयर myClassA या myClassB प्रकार का उपयोग करेगा। एक बेमेल पर, मुझे डेटा परिवर्तित करने में समय बिताने की आवश्यकता है।

switch ((typeid(T)) {
  case typeid(myClassA):
    // handle that case
    break;
  case typeid(myClassB):
    // handle that case
    break;
  case typeid(uint32_t):
    // handle that case
    break;
  default:
    // handle that case
}

1
TypeId: मैं Arduino पर टाइपिड () का उपयोग करने में सक्षम नहीं था। इसके अलावा टाइपिड () एक रनटाइम चेक है, न कि संकलन समय ताकि इसे अनुकूलित कोड उत्पन्न करने के लिए उपयोग नहीं किया जा सके।
Dan Truong

1
हाँ, नहीं, यह वह नहीं करता है जो आपने सोचा था कि यह किया है। typeidबस परिभाषा के आधार पर एक स्थिर, संकलन-समय की जांच नहीं हो सकती है - इसलिए यह किसी भी अनुकूलन की सुविधा नहीं देता है। For a template function, I need to special case the code based on the template variableसही है, तो आप वास्तव में क्या चाहते हैं CRTP मुहावरे के माध्यम से स्थिर बहुरूपता है। यह वही है जो हासिल करता है।
अंडरस्कोर_ड

4

मुझे यकीन नहीं है कि अगर मेरा जवाब मदद करेगा।

संक्षिप्त उत्तर है, आपको इसका उपयोग करने के लिए किसी चर के प्रकार की वास्तव में आवश्यकता नहीं है / जानना चाहते हैं।

यदि आपको एक स्थिर चर को एक प्रकार देने की आवश्यकता है, तो आप बस ऑटो का उपयोग कर सकते हैं।

अधिक परिष्कृत मामले में जहां आप एक क्लास या स्ट्रक्चर में "ऑटो" का उपयोग करना चाहते हैं, मैं सुझाव देता हूं कि आप डिक्लेपट के साथ टेम्पलेट का उपयोग करें।

उदाहरण के लिए, मान लें कि आप किसी और की लाइब्रेरी का उपयोग कर रहे हैं और इसमें "अज्ञात_वर" नामक एक चर है और आप इसे किसी वेक्टर या संरचना में रखना चाहेंगे, आप इसे पूरी तरह से कर सकते हैं:

template <typename T>
struct my_struct {
    int some_field;
    T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector

उम्मीद है की यह मदद करेगा।

संपादित करें: अच्छे उपाय के लिए, यहां सबसे जटिल मामला है जिसके बारे में मैं सोच सकता हूं: अज्ञात प्रकार का वैश्विक चर होना। इस स्थिति में आपको c ++ 14 और टेम्पलेट चर की आवश्यकता होगी।

कुछ इस तरह:

template<typename T> vector<T> global_var;

void random_func (auto unknown_var) {
    global_var<decltype(unknown_var)>.push_back(unknown_var);
}

यह अभी भी थोड़ा थकाऊ है, लेकिन यह उतना ही करीब है जितना कि आप टाइपलेस भाषाओं को प्राप्त कर सकते हैं। जब भी आप टेम्प्लेट चर का संदर्भ लें, तो यह सुनिश्चित करें कि हमेशा टेम्प्लेट विनिर्देश को वहां रखें।



0

यदि आपको एक वर्ग और ज्ञात प्रकार के बीच तुलना करने की आवश्यकता है, उदाहरण के लिए:

class Example{};
...
Example eg = Example();

आप इस तुलना लाइन का उपयोग कर सकते हैं:

bool isType = string( typeid(eg).name() ).find("Example") != string::npos;

जो typeidनाम की जाँच करता है, उसमें स्ट्रिंग प्रकार होता है (टाइपिड नाम में अन्य मैंगल्ड डेटा होता है, इसलिए इसके s1.find(s2)बजाय यह सर्वोत्तम है ==)।


-2

आप निश्चित रूप से जा सकते हैं typeid(x).name()जहां x चर नाम है। यह वास्तव में डेटा प्रकार के लिए एक कास्ट चार पॉइंटर लौटाता है। अब, निम्नलिखित कोड को देखें।

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n = 36;
    char c = 'A';
    double d = 1.2;
    if(*(typeid(n).name()) == 'i'){
        cout << "I am an Integer variable" << endl;
    }
    if(*((char *) typeid(d).name()) == 'd'){
        cout << "I am a Double variable" << endl;
    }
    if(*((char *) typeid(c).name()) == 'c'){
        cout << "I am a Char variable" << endl;
    }
    return 0;
}

ध्यान दें कि यदि पहला और दूसरा दोनों काम करता है।


पहले चरित्र द्वारा प्रकार को पहचानना बहुत बुरा विचार है।
दिमित्री कुज़मिनोव

क्या आप कृपया अधिक विशिष्ट दिमित्री हो सकते हैं? मुझे आपकी बात यहां नहीं लगी।
पिकाचू

इसे बस छोटा किया जा सकता है std::cout << "I'm a variable of type " << typeid(n).name()। (एक / एक कलाकृतियों को रोकने के लिए reworded, लेकिन यह एक और जाँच के साथ तय किया जा सकता है)। फिर भी, यदि आप पूरी तरह से तुलना चाहते हैं, तो ऐसा करना बहुत बेहतर हैtypeid(n) == typeid(int)
जो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.