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

Как правильно определить тип переменной в 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

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

7

Решение

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

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

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

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

РЕДАКТИРОВАТЬ Используя Boost, вы можете попробовать std::cout << boost::typeindex::type_id<decltype(a)>().pretty_name() << std::endl;, увидеть Получение удобочитаемых и искаженных имен типов

13

Другие решения

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

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

G ++ реализует typeid(...).name() такой, что он возвращает искаженное имя типа ABI. Это особый способ представления типов, который используется в скомпилированных объектных файлах и библиотеках. Если вы скомпилируете код 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», который представляет тип второго аргумента. Этот символ используется для идентификации функции в двоичном объектном файле, в индексах библиотеки, другими скомпилированными объектами, которые хотят связать эту функцию и т. Д.

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

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

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

Itanium ABI определяет дополнительная функция для разборки. Вот пример, использующий это.

3

Имена типов не должны быть такими, как вы ожидаете. Увидеть этот ответ для способа получить фактическое имя типа. Обратите внимание — он работает только на gcc и, с некоторыми дополнительная установка, на лязг.

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

2
По вопросам рекламы [email protected]