'typeid' против 'typeof' в C ++
Вопрос
Мне интересно, в чем разница между typeid
и typeof
на языке C++.Вот что я знаю:
typeid
упоминается в документации для тип_инфо который определен в заголовочном файле C ++ typeinfo.typeof
определяется в расширении GCC для C и в C ++ Повышение библиотека.
Кроме того, вот тестовый код test, который я создал, где я обнаружил, что typeid
возвращает не то, что я ожидал.Почему?
main.cpp
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person {
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person {
// ... Employee members ...
};
int main () {
Person person;
Employee employee;
Person *ptr = &employee;
int t = 3;
std::cout << typeid(t).name() << std::endl;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer
// to a polymorphic class)
}
выходной сигнал:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
Решение
В языке C++ нет такого понятия, как typeof
.Должно быть, вы ищете какое-то расширение, специфичное для компилятора.Если вы говорите о GCC typeof
, то аналогичная функция присутствует в C++11 через ключевое слово decltype
.Опять же, в C++ такого нет. typeof
ключевое слово.
typeid
— это оператор языка C++, который возвращает информацию идентификации типа во время выполнения.По сути, он возвращает type_info
объект, который сравним по равенству с другими type_info
объекты.
Обратите внимание, что единственное определенное свойство возвращаемого type_info
Объект имеет то, что он сравним по равенству и неравенству, т.е. type_info
объекты, описывающие разные типы, должны сравниваться неравными, а type_info
объекты, описывающие один и тот же тип, должны сравниваться равными.Все остальное определяется реализацией.Методы, возвращающие различные «имена», не гарантированно возвращают что-либо удобочитаемое, и даже не гарантированно возвращают что-либо вообще.
Также обратите внимание, что вышеизложенное, вероятно, подразумевает (хотя стандарт, похоже, не упоминает об этом явно), что последовательное применение typeid
к одному и тому же типу могут возвращаться разные type_info
объекты (которые, конечно, все равно придется сравнивать равными).
Другие советы
Основное различие между ними заключается в следующем
- typeof — это конструкция времени компиляции, которая возвращает тип, определенный во время компиляции.
- typeid — это конструкция времени выполнения и, следовательно, предоставляет информацию о типе значения во время выполнения.
Тип ссылки: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
идентификатор типа https://en.wikipedia.org/wiki/Typeid
typeid
может работать во время выполнения и возвращать объект, описывающий тип объекта во время выполнения, который должен быть указателем на объект класса с виртуальными методами, чтобы RTTI (информация о типе времени выполнения) храниться в классе.Он также может указать тип выражения во время компиляции или имя типа, если не указан указатель на класс с информацией о типе во время выполнения.
typeof
является расширением GNU и дает вам тип любого выражения во время компиляции.Это может быть полезно, например, при объявлении временных переменных в макросах, которые могут использоваться с несколькими типами.В C++ вы обычно используете шаблоны вместо.
Отвечая на дополнительный вопрос:
мой следующий тестовый код для typeid не выводит правильное имя типа.что случилось?
Здесь нет ничего плохого.То, что вы видите, является строковым представлением имени типа.Стандартный C ++ не заставляет компиляторы выдавать точное имя класса, только разработчик (поставщик компилятора) должен решить, что подходит.Короче говоря, названия зависят от компилятора.
Это два разных инструмента. typeof
возвращает тип выражения, но оно не является стандартным.В C ++ 0x есть нечто, называемое decltype
который выполняет ту же работу, AFAIK.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
Принимая во внимание , что typeid
используется с полиморфными типами.Например, предположим, что cat
выводит animal
:
animal* a = new cat; // animal has to have at least one virtual function
...
if( typeid(*a) == typeid(cat) )
{
// the object is of type cat! but the pointer is base pointer.
}
typeid предоставляет тип данных во время выполнения, когда их запрашивают.Typedef - это конструкция времени компиляции, которая определяет новый тип, как указано после этого.В C ++ нет typeof Выходные данные отображаются как (показаны в виде встроенных комментариев):
std::cout << typeid(t).name() << std::endl; // i
std::cout << typeid(person).name() << std::endl; // 6Person
std::cout << typeid(employee).name() << std::endl; // 8Employee
std::cout << typeid(ptr).name() << std::endl; // P6Person
std::cout << typeid(*ptr).name() << std::endl; //8Employee
Вы можете использовать Boost demangle, чтобы создать красивое имя:
#include <boost/units/detail/utility.hpp>
и что-то вроде
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);