Как определить тип переменной

Как правильно определить тип переменной в C++. Я попытался определить тип переменной:

int a = 5;
std::cout << typeid(a).name() << std::endl;

и вместо ожидаемого вывода int он дает вам:

i

Я очень смущен, почему это происходит.. Его как-то дает вам только первую букву типа, который вы объявляете переменной. Int не единственный... также это:

 char a = 'A'
 std::cout << typeid(a).name() << std::endl;

Example Program

есть простой обходной путь для этого? Любая помощь будет оценена!

3 ответов


есть две проблемы с вашим кодом,

во-первых typeid(..).name() возвращает строку, определенную реализацией, это может быть любая допустимая строка, она может возвращать "" для каждого типа он может даже возвращать разные значения для каждого выполнения программы (хотя я считаю, что значение не может измениться во время выполнения). GCC (и лязг?) возвращает нечитаемые имена, тогда как Visual C++ возвращает разумные (в данном случае int)

во-вторых, если типа a - это полиморфный тип, typeid(a) вернет typeid соответствует динамическому типу a а не тип, который использовался для объявления a, вместо того, чтобы использовать typeid(decltype(a)).

к сожалению, нет стандартного способа получить имя типа таким образом, чтобы он был удобочитаемым или правильным синтаксисом C++. (см. Unmangling результат в std::type_info::имя если вы хотите способ, который работает в GCC)

редактировать используя Boost, вы можете попробовать std::cout << boost::typeindex::type_id<decltype(a)>().pretty_name() << std::endl; см. получение читаемых человеком и искаженных имен типов


Я имею в виду, даже если это не понятно. Например, если int 32432423423403095590353095309530953, то он всегда будет таким же. Поэтому я могу легко установить функцию для возврата типа переменной...

результаты ты уже исполнить. Возможно, это поможет объяснить, как именно реализация C++, которую вы используете, получает строки, которые вы видите.

G++ и реализует typeid(...).name() такой, что он возвращает "ABI mangled" имя тип. Это особый способ представления типов, который используется в скомпилированных объектных файлов и библиотек. Если вы скомпилируете код C++ в сборку, вы увидите "символы", которые определяют, с какой функцией или данными связан результирующий код сборки. Например, возьмем функцию:

int foo(double a, char b) {
    return a + b;
}

скомпилировать его в сборку, и вы увидите что-то вроде следующего:

_Z3foodc:
.LFB0:
    .cfi_startproc
    movsbl  %dil, %edi
    cvtsi2sd    %edi, %xmm1
    addsd   %xmm1, %xmm0
    cvttsd2si   %xmm0, %eax
    ret
    .cfi_endproc

первая строка здесь-это "искореженный" символ, который используется для идентификации функция int foo(double,char). Он содержит "Z3foo", который представляет имя функции, а затем "d", который представляет тип первого аргумента и "c", который представляет тип второго аргумента. Этот символ используется для обозначения функции в двоичный объектный файл, в индексах библиотеки, другие скомпилированные объекты, которые хотите привязать к этой функции и т. д.

вы можете символы demangle С помощью инструмента c++filt. Этот инструмент сканирует любой текст, который вы передаете его в поисках вещи, которые соответствуют синтаксису mangling и преобразуют их во что-то более похожее на то, как эти типы называются в исходном коде C++.

g++ реализует Itanium C++ ABI схема коверкание. Он используется большинством компиляторов платформы unix.

Итак, вернемся к вашему коду, угадайте, как тип " int " представлен в этих символах.

Itanium ABI указывает дополнительная функция для demangling. здесь an пример использования.


имена типов не должны быть такими, какими вы их ожидаете. См.ответ для того, чтобы получить фактическое имя типа. Примечание - он работает только на gcc и, с некоторыми дополнительные установки, на Clang.

С Visual C++ вы должны вызвать UnDecorateSymbolName, но, по-видимому ints называются int здесь