Di C ++, bagaimana cara menemukan tipe variabel?
Di C ++, bagaimana cara menemukan tipe variabel?
Jawaban:
Anda dapat menggunakan operator typeid :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
Berarti integer pada kompiler Anda. Nama yang dikembalikan tidak ditentukan oleh standar.
typeid
sangat disingkat, khusus untuk kompiler, dan tidak dimaksudkan untuk konsumsi manusia. Anda dapat "memisahkan" mereka (itu istilah sebenarnya!), Baik dalam kode dengan sesuatu seperti gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , dengan utilitas baris perintah seperti c++filt
, atau dengan berbagai demangler online seperti demangler.com .
Jika Anda memiliki variabel
int k;
Anda bisa mendapatkan tipenya menggunakan
cout << typeid(k).name() << endl;
Lihat utas berikut di SO: Pertanyaan serupa
Perbedaan utama antara C ++ dan Javascript adalah C ++ adalah bahasa dengan tipe statis, sedangkan javascript bersifat dinamis.
Dalam bahasa yang diketik dinamis, sebuah variabel dapat berisi apa saja, dan tipenya diberikan oleh nilai yang dimilikinya, saat demi saat. Dalam bahasa tipe statis, tipe variabel dideklarasikan, dan tidak bisa diubah.
Mungkin ada pengiriman dinamis dan komposisi objek dan subtipe (pewarisan dan fungsi virtual) serta pengiriman statis dan supertyping (melalui CRTP template), tetapi dalam hal apa pun jenis variabel harus diketahui oleh penyusun.
Jika Anda berada dalam posisi untuk tidak tahu apa itu atau bisa jadi, itu karena Anda merancang sesuatu karena bahasa memiliki sistem tipe dinamis.
Jika itu kasusnya, Anda sebaiknya memikirkan kembali desain Anda, karena akan memasuki negeri yang tidak sesuai dengan bahasa yang Anda gunakan (kebanyakan seperti berjalan di jalan raya dengan ulat, atau di dalam air dengan mobil)
Biasanya, ingin mencari tipe variabel di C ++ adalah pertanyaan yang salah. Ini cenderung menjadi sesuatu yang Anda bawa dari bahasa prosedural seperti misalnya C atau Pascal.
Jika Anda ingin membuat kode untuk perilaku yang berbeda tergantung pada tipenya, coba pelajari tentang misal kelebihan beban fungsi dan pewarisan objek . Ini tidak akan langsung masuk akal pada hari pertama Anda menggunakan C ++, tetapi terus lakukan.
Saya yakin saya memiliki kasus penggunaan yang valid untuk menggunakan typeid (), cara yang sama berlaku untuk menggunakan sizeof (). Untuk fungsi template, saya perlu membuat kode kasus khusus berdasarkan variabel template, sehingga saya menawarkan fungsionalitas dan fleksibilitas maksimum.
Ini jauh lebih kompak dan dapat dipelihara daripada menggunakan polimorfisme, untuk membuat satu contoh fungsi untuk setiap jenis yang didukung. Bahkan dalam hal ini saya mungkin menggunakan trik ini untuk menulis badan fungsi hanya sekali:
Perhatikan bahwa karena kode menggunakan templat, pernyataan sakelar di bawah ini harus menyelesaikan secara statis menjadi hanya satu blok kode, mengoptimalkan semua kasus palsu, AFAIK.
Pertimbangkan contoh ini, di mana kita mungkin perlu menangani konversi jika T adalah satu jenis vs jenis lainnya. Saya menggunakannya untuk spesialisasi kelas untuk mengakses perangkat keras di mana perangkat keras tersebut akan menggunakan jenis myClassA atau myClassB. Jika ada ketidakcocokan, saya perlu menghabiskan waktu untuk mengonversi data.
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
tidak bisa menjadi pemeriksaan waktu kompilasi statis - menurut definisi - jadi ini tidak memfasilitasi pengoptimalan apa pun. For a template function, I need to special case the code based on the template variable
Benar, jadi yang Anda inginkan adalah polimorfisme statis melalui idiom CRTP. Inilah yang dicapai.
Saya tidak yakin apakah jawaban saya akan membantu.
Jawaban singkatnya adalah, Anda tidak benar-benar perlu / ingin mengetahui jenis variabel untuk menggunakannya.
Jika Anda perlu memberikan tipe ke variabel statis, maka Anda dapat menggunakan auto.
Dalam kasus yang lebih canggih di mana Anda ingin menggunakan "auto" di kelas atau struct, saya sarankan menggunakan template dengan jenis deklarasi.
Misalnya, Anda menggunakan library orang lain dan memiliki variabel yang disebut "unknown_var" dan Anda ingin memasukkannya ke dalam vektor atau struct, Anda dapat melakukan ini sepenuhnya:
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
Semoga ini membantu.
EDIT: Untuk ukuran yang baik, berikut adalah kasus paling kompleks yang dapat saya pikirkan: memiliki variabel global jenis yang tidak diketahui. Dalam hal ini Anda membutuhkan c ++ 14 dan variabel template.
Sesuatu seperti ini:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
Ini masih agak membosankan tetapi sedekat mungkin dengan bahasa tanpa ketikan. Pastikan setiap kali Anda mereferensikan variabel template, selalu letakkan spesifikasi template di sana.
Jika Anda perlu membuat perbandingan antara kelas dan tipe yang diketahui, misalnya:
class Example{};
...
Example eg = Example();
Anda dapat menggunakan baris perbandingan ini:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
yang memeriksa typeid
nama yang berisi tipe string (nama typeid memiliki data rusak lainnya, jadi sebaiknya lakukan a s1.find(s2)
daripada ==
).
Anda pasti bisa memilih di typeid(x).name()
mana x adalah nama variabel. Ini sebenarnya mengembalikan pointer char const ke tipe data. Sekarang, lihat kode berikut.
#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;
}
Perhatikan bagaimana pertama dan kedua keduanya jika berhasil.
std::cout << "I'm a variable of type " << typeid(n).name()
. (dibuat ulang untuk mencegah artefak a / an, tetapi itu dapat diperbaiki dengan pemeriksaan lain). Meskipun demikian, jika Anda benar-benar menginginkan perbandingan, itu jauh lebih baik untuk dilakukantypeid(n) == typeid(int)