Jak w C ++ znaleźć typ zmiennej?
Jak w C ++ znaleźć typ zmiennej?
Odpowiedzi:
Możesz użyć operatora typeid :
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
i
oznacza liczbę całkowitą na twoim kompilatorze. Zwracane nazwy nie są określone przez standard.
typeid
są bardzo skrócone, specyficzne dla kompilatora i nie są przeznaczone do spożycia przez ludzi. Możesz je „rozszyfrować” (to jest rzeczywisty termin!), Albo w kodzie za pomocą czegoś takiego jak gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html , za pomocą narzędzi wiersza poleceń, takich jak c++filt
, lub za pomocą dowolnego z różnych demanglerów online takie jak demangler.com .
Jeśli masz zmienną
int k;
Możesz uzyskać jego typ za pomocą
cout << typeid(k).name() << endl;
Zobacz następujący wątek na SO: Podobne pytanie
Główną różnicą między C ++ a Javascriptem jest to, że C ++ jest językiem z typowaniem statycznym, a wile javascript jest dynamiczny.
W językach z typami dynamicznymi zmienna może zawierać dowolną rzecz, a jej typ jest określony chwilą przez wartość, jaką posiada. W językach statycznych typ zmiennej jest deklarowany i nie można go zmienić.
Może istnieć dynamiczne wysyłanie i skład obiektów i podtypowanie (dziedziczenie i funkcje wirtualne), a także wysyłanie statyczne i supertyping (za pośrednictwem szablonu CRTP), ale w każdym przypadku kompilator musi znać typ zmiennej.
Jeśli możesz nie wiedzieć, co to jest lub może być, to dlatego, że coś zaprojektowałeś, ponieważ język ma dynamiczny system typów.
Jeśli tak jest, lepiej przemyśleć swój projekt, ponieważ wjeżdża on do krainy, która nie jest naturalna dla języka, którego używasz (najbardziej przypomina jazdę autostradą z gąsienicą lub jazdę samochodem w wodzie)
Zwykle chęć znalezienia typu zmiennej w C ++ jest złym pytaniem. Zwykle jest to coś, co nosisz z języków proceduralnych, takich jak na przykład C lub Pascal.
Jeśli chcesz zakodować różne zachowania w zależności od typu, spróbuj dowiedzieć się np. O przeciążaniu funkcji i dziedziczeniu obiektów . Nie będzie to miało natychmiastowego sensu pierwszego dnia C ++, ale trzymaj się tego.
Uważam, że mam ważny przypadek użycia dla używania typeid (), w ten sam sposób, w jaki jest ważne, aby użyć sizeof (). W przypadku funkcji szablonu potrzebuję specjalnego przypadku kodu opartego na zmiennej szablonu, aby zaoferować maksymalną funkcjonalność i elastyczność.
Tworzenie jednej instancji funkcji dla każdego obsługiwanego typu jest znacznie bardziej zwarte i łatwiejsze w utrzymaniu niż użycie polimorfizmu. Nawet w takim przypadku mógłbym użyć tej sztuczki, aby napisać treść funkcji tylko raz:
Zwróć uwagę, że ponieważ kod używa szablonów, poniższa instrukcja switch powinna zostać rozwiązana statycznie tylko do jednego bloku kodu, optymalizując wszystkie fałszywe przypadki, AFAIK.
Rozważ ten przykład, w którym może być konieczne obsłużenie konwersji, jeśli T jest jednym z typów. Używam go do specjalizacji klasowej, aby uzyskać dostęp do sprzętu, w którym sprzęt będzie używał typu myClassA lub myClassB. W przypadku niezgodności muszę poświęcić czas na konwersję danych.
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
po prostu nie może być statyczną kontrolą czasu kompilacji - z definicji - więc nie ułatwia to żadnej optymalizacji. For a template function, I need to special case the code based on the template variable
Tak, więc to, czego naprawdę chcesz, to statyczny polimorfizm za pośrednictwem idiomu CRTP. Dokładnie to osiąga.
Nie jestem pewien, czy moja odpowiedź pomogłaby.
Krótka odpowiedź brzmi: tak naprawdę nie potrzebujesz / nie chcesz znać typu zmiennej, aby jej użyć.
Jeśli chcesz nadać typ zmiennej statycznej, możesz po prostu użyć auto.
W bardziej wyrafinowanym przypadku, gdy chcesz użyć „auto” w klasie lub strukturze, sugerowałbym użycie szablonu z decltype.
Na przykład, powiedzmy, że korzystasz z biblioteki innej osoby i ma ona zmienną o nazwie „unknown_var” i chcesz umieścić ją w wektorze lub strukturze, możesz całkowicie to zrobić:
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
Mam nadzieję że to pomoże.
EDYCJA: Na dokładkę, oto najbardziej złożony przypadek, jaki przychodzi mi do głowy: posiadanie zmiennej globalnej nieznanego typu. W takim przypadku potrzebujesz C ++ 14 i zmiennej szablonu.
Coś takiego:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
Wciąż jest to trochę uciążliwe, ale jest tak bliskie, jak to tylko możliwe, do języków bez maszyny. Po prostu upewnij się, że za każdym razem, gdy odwołujesz się do zmiennej szablonu, zawsze umieszczaj tam specyfikację szablonu.
Jeśli chcesz dokonać porównania między klasą a znanym typem, na przykład:
class Example{};
...
Example eg = Example();
Możesz użyć tej linii porównawczej:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
która sprawdza, czy typeid
nazwa zawiera typ string (nazwa typu typeid ma inne zniekształcone dane, więc najlepiej jest zrobić s1.find(s2)
zamiast ==
).
Zdecydowanie możesz wybrać, typeid(x).name()
gdzie x jest nazwą zmiennej. W rzeczywistości zwraca wskaźnik const char do typu danych. Teraz spójrz na poniższy kod.
#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;
}
Zwróć uwagę, jak działa pierwszy i drugi.
std::cout << "I'm a variable of type " << typeid(n).name()
. (przeredagowano, aby zapobiec artefaktom / an, ale można to naprawić za pomocą innego sprawdzenia). Nawet wtedy, jeśli absolutnie chcesz porównania, o wiele lepiej to zrobićtypeid(n) == typeid(int)