C ++ 'da, bir değişkenin türü nasıl bulunur?
C ++ 'da, bir değişkenin türü nasıl bulunur?
Yanıtlar:
Typeid operatörünü kullanabilirsiniz :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
derleyicinizdeki tam sayı anlamına gelir. Döndürülen isimler standart tarafından belirtilmemiştir.
typeid
çok kısaltılmıştır, derleyiciye özeldir ve insan tüketimi için tasarlanmamıştır. Şunları yapabilirsiniz "demangle" Onları (o fiili terim!), Ya gibi bir şeyle kodunda gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html gibi komut satırı uygulamaları ile, c++filt
veya çeşitli çevrimiçi demanglers herhangi biriyle demangler.com gibi .
Bir değişkeniniz varsa
int k;
Türünü kullanarak alabilirsiniz
cout << typeid(k).name() << endl;
SO'da şu konu başlığına bakın: Benzer soru
C ++ ve Javascript arasındaki temel fark, C ++ 'nın statik tipte bir dil olmasıdır, wile javascript dinamiktir.
Dinamik tipli dillerde bir değişken her şeyi içerebilir ve türü an be an tuttuğu değerle verilir. Statik yazılan dillerde bir değişkenin türü bildirilir ve değiştirilemez.
Dinamik gönderme ve nesne oluşturma ve alt tipleme (kalıtım ve sanal işlevler) yanı sıra statik gönderme ve süper tipleme (şablon CRTP aracılığıyla) olabilir, ancak her durumda değişkenin türü derleyici tarafından bilinmelidir.
Ne olduğunu veya ne olabileceğini bilemeyecek bir konumdaysanız, bunun nedeni dilin dinamik bir yazı sistemine sahip olması nedeniyle bir şey tasarlamış olmanızdır.
Eğer durum buysa, kullandığınız dil için doğal olmayan bir ülkeye gireceği için tasarımınızı yeniden düşünmeniz daha iyi olur (en çok tırtılla otoyolda veya araba ile suda gitmek gibi)
Genellikle, C ++ 'da bir değişkenin türünü bulmak istemek yanlış sorudur. C veya Pascal gibi prosedürel dillerden taşıdığınız bir şey olma eğilimindedir.
Türe bağlı olarak farklı davranışları kodlamak istiyorsanız, örneğin fonksiyon aşırı yükleme ve nesne mirası hakkında bilgi edinmeye çalışın . Bu, ilk C ++ gününüzde hemen bir anlam ifade etmeyecek, ancak devam edin.
Typeid () kullanmak için geçerli bir kullanım örneğim olduğuna inanıyorum, aynı sizeof () kullanmak için geçerli olduğu gibi. Bir şablon işlevi için, maksimum işlevsellik ve esneklik sunabilmem için, şablon değişkenine dayalı olarak kodu özel bir duruma getirmem gerekir.
Desteklenen her tür için işlevin bir örneğini oluşturmak, polimorfizm kullanmaktan çok daha kompakt ve bakımı yapılabilir. Bu durumda bile, işlevin gövdesini yalnızca bir kez yazmak için bu numarayı kullanabilirim:
Kod şablonlar kullandığından, aşağıdaki switch ifadesinin statik olarak tek bir kod bloğuna çözümlenmesi ve tüm yanlış durumları (AFAIK) ortadan kaldırması gerektiğini unutmayın.
T bir türe karşı diğeri ise, bir dönüşümü ele almamız gerekebilecek bu örneği düşünün. Bunu, donanımın myClassA veya myClassB türünü kullanacağı donanıma erişmek için sınıf uzmanlığı için kullanıyorum. Bir uyumsuzluk durumunda, verileri dönüştürmek için zaman harcamam gerekiyor.
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
}
typeid
statik, derleme zamanı denetimi olamaz - tanım gereği - bu nedenle bu herhangi bir optimizasyonu kolaylaştırmaz. For a template function, I need to special case the code based on the template variable
Doğru, yani gerçekten istediğiniz şey, CRTP deyimi aracılığıyla statik polimorfizmdir. Bu tam olarak bunu başarır.
Cevabımın yardımcı olup olmayacağından emin değilim.
Kısa cevap, onu kullanmak için bir değişkenin türünü gerçekten bilmenize gerek yoktur / bilmek istemezsiniz.
Statik değişkene bir tür vermeniz gerekiyorsa, o zaman basitçe auto kullanabilirsiniz.
Bir sınıfta veya yapıda "auto" kullanmak istediğiniz daha karmaşık bir durumda, decltype ile şablon kullanmanızı öneririm.
Örneğin, başka birinin kitaplığını kullandığınızı ve "bilinmeyen_var" adında bir değişkeni olduğunu ve bunu bir vektör veya yapıya koymak istediğinizi varsayalım, bunu tamamen yapabilirsiniz:
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
Bu yardımcı olur umarım.
DÜZENLEME: İyi bir ölçü için, işte aklıma gelen en karmaşık durum: bilinmeyen türde küresel bir değişkene sahip olmak. Bu durumda c ++ 14 ve şablon değişkenine ihtiyacınız olacaktır.
Bunun gibi bir şey:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
Hala biraz sıkıcı ama yazısız dillere olabildiğince yakın. Şablon değişkenine başvurduğunuzda, daima şablon özelliğini oraya yerleştirdiğinizden emin olun.
Bir sınıf ile bilinen bir tür arasında bir karşılaştırma yapmanız gerekirse, örneğin:
class Example{};
...
Example eg = Example();
Bu karşılaştırma satırını kullanabilirsiniz:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
bu, typeid
adın dize türünü içerdiğini kontrol eder (typeid adında başka karıştırılmış veriler vardır, bu nedenle en iyisi bir s1.find(s2)
yerine yapmaktır ==
).
typeid(x).name()
X'in değişken adı olduğu yere kesinlikle gidebilirsiniz . Aslında veri türüne bir const char gösterici döndürür. Şimdi aşağıdaki koda bakın.
#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;
}
Her ikisinin de işe yaradığına dikkat edin.
std::cout << "I'm a variable of type " << typeid(n).name()
. (a / an artefaktları önlemek için yeniden ifade edildi, ancak bu başka bir kontrolle düzeltilebilir). O zaman bile, kesinlikle bir karşılaştırma istiyorsanız, yapmak çok daha iyitypeid(n) == typeid(int)