Nazwy zwracane przez typeidsą 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 .
cincodenada
33
W przypadku stwierdzeń statycznych wprowadzono C ++ 11, decltypeco jest bardzo przydatne w niektórych scenariuszach.
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)
Jeśli C ++ ma dynamiczną zmianę, myślę, że byłoby świetnie, a funkcje typu i parseInt, parseFloat również się przydadzą, ale nie wiem, dlaczego twórcy C ++ na przykład utrudniają to! kto mówi, że dobrze jest napisać cout << "String"
Waqas Tahir
determinacja jest najlepsza !!!! #include <sstream> string str ("1912"); int strtointval; stringstream (str) >> strtointval;
Waqas Tahir
@Waqas Uh, co? Ludzie, którzy twierdzą, że jest najlepszy, to ludzie, którzy definiują język, a IMO mają prawie ostatnie słowo z nim związane - na przykład dobre praktyki kodowania. Czy mógłbyś przeformułować ten komentarz, aby miał więcej sensu?
Załóż pozew Moniki
Całkowicie się nie zgadzam. Java, C #, PHP, Perl, Python i tak dalej zostały zaprojektowane w C i C ++ i nie są gąsienicami. (Kiedy tworzysz aplikację bazodanową do otwierania tabel zmiennych z 'nieznanych' baz danych, musisz kontrolować typ pola na schemat zmiennych i vice vera w 'bardzo' dynamiczny sposób;))
TomeeNS
@TomeeNS: Nie. Są napisane w C i C ++, a nie zaprojektowane . Są przeznaczone do wykonywania swoich zadań i mają typ dynamiczny, nawet jeśli same C i C ++ tego nie robią. Nie ma w tym nic dziwnego.
Emilio Garavaglia
8
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.
Niezupełnie, powiedzmy, że masz klasę Object i podklasę Book. Teraz wyobraź sobie, że masz pudełko, które może przechowywać wiele obiektów, ale z jakiegoś powodu chcesz wyświetlić listę wszystkich książek w nim. Sprawdzanie typu jest dużo czystsze niż dodanie metody „type” do Object, a następnie zastąpienie jej w Book, aby otrzymać coś takiego jak „book”
Paulo Cesar
Jak w przypadku każdej reguły, istnieją wyjątki (stąd moje „zwykle”!), A kontenery mają tendencję do zwiększania złożoności teorii typów. Nigdy nie przepadałem za pojemnikami-obiektami-polimorficznymi… w większości przypadków, szablony jednorodnych typów pojemników są wystarczające i są znacznie czystsze.
Pontus Gagge
Nie używasz szablonów?
Bryan Grace
6
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)){casetypeid(myClassA):// handle that casebreak;casetypeid(myClassB):// handle that casebreak;casetypeid(uint32_t):// handle that casebreak;default:// handle that case}
TypeId: nie udało mi się użyć typeid () na Arduino. Również typeid () jest sprawdzaniem w czasie wykonywania , a nie czasem kompilacji, więc nie może być używane do generowania zoptymalizowanego kodu.
Dan Truong,
1
Tak, nie, to nie robi tego, co myślałeś. typeidpo 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 variableTak, więc to, czego naprawdę chcesz, to statyczny polimorfizm za pośrednictwem idiomu CRTP. Dokładnie to osiąga.
underscore_d
4
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.
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.
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>usingnamespace 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;}return0;}
Rozpoznawanie typu przez pierwszą postać to bardzo zły pomysł.
Dmitry Kuzminov
Czy możesz być bardziej konkretny, Dmitry? Nie rozumiem, o co ci tutaj chodzi.
Pikachu
Można to po prostu skrócić do 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)
Odpowiedzi:
Możesz użyć operatora typeid :
źródło
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 jakc++filt
, lub za pomocą dowolnego z różnych demanglerów online takie jak demangler.com .W przypadku stwierdzeń statycznych wprowadzono C ++ 11,
decltype
co jest bardzo przydatne w niektórych scenariuszach.źródło
Jeśli masz zmienną
Możesz uzyskać jego typ za pomocą
Zobacz następujący wątek na SO: Podobne pytanie
źródło
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)
źródło
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.
źródło
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.
źródło
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ć:
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:
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.
źródło
źródło
Jeśli chcesz dokonać porównania między klasą a znanym typem, na przykład:
Możesz użyć tej linii porównawczej:
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==
).źródło
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.Zwróć uwagę, jak działa pierwszy i drugi.
źródło
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)