Мне интересно, в чем разница между typeid
и typeof
в C ++. Вот что я знаю:
typeid
упоминается в документации для type_info, которая определена в заголовочном файле C ++ typeinfo .typeof
определяется в расширении GCC для C и в библиотеке C ++ Boost .
Кроме того, вот тестовый код, который я создал, где я обнаружил, 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
name()
реализацией. Это не обязательно должно быть допустимое имя идентификатора C ++, просто то, что однозначно идентифицирует тип. Похоже, ваша реализация использует общую схему компиляции имен компилятора.Ответы:
Язык С ++ не имеет такого понятия, как
typeof
. Вы должны искать какое-то специфичное для компилятора расширение. Если вы говорите о GCCtypeof
, то подобная функция присутствует в C ++ 11 через ключевое словоdecltype
. Опять же, C ++ не имеет такогоtypeof
ключевого слова.typeid
является оператором языка C ++, который возвращает информацию идентификации типа во время выполнения Он в основном возвращаетtype_info
объект, который равен равенству с другимиtype_info
объектами.Обратите внимание, что единственным определенным свойством возвращаемого
type_info
объекта является его сопоставимость по равенству и неравенству, т. Е.type_info
Объекты, описывающие разные типы, должны сравниваться неравно, в то время какtype_info
объекты, описывающие один и тот же тип, должны сравниваться одинаково. Все остальное определяется реализацией. Методы, которые возвращают различные «имена», не гарантируют возвращение чего-либо понятного человеку, и даже не гарантируют, что они вообще что-либо будут возвращать.Также обратите внимание, что приведенное выше, вероятно, подразумевает (хотя стандарт, по-видимому, не упоминает об этом явно), что последовательные применения одного
typeid
и того же типа могут возвращать разныеtype_info
объекты (которые, конечно, все равно должны сравниваться).источник
decltype
? Я не уверен, какова общая политика, но так как вопрос помечен,C++
я ожидаю, что он будет ссылаться на последний стандарт. Повторная пометка вопросаC++03
также будет вариант imho. Лично меня иногда очень смущает, так как я вынужден использовать preC ++ 11 на работе, а иногда я не уверен, что такое «pre11» или «post11».decltype
это не заменаtypeof
.typeof
работает над типами, а покаdecltype
нет. Например,typeof(int)
это вint
то время какdecltype(int)
ошибка.type_info
объекты, описывающие разные типы, должны сравниваться неравно» . На самом деле, это не гарантировано . Оператор неравенства был удален в C ++ 20, чтобы (я полагаю) препятствовать использованию разных типов, сравнивающих неравные. Но если подумать, равенство не безопасно, если неравенство небезопасно.Основное различие между ними заключается в следующем
Тип ссылки: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
Ссылка на typeid: https://en.wikipedia.org/wiki/Typeid
источник
typeid
может работать во время выполнения и возвращать объект, описывающий тип времени выполнения объекта, который должен быть указателем на объект класса с виртуальными методами, чтобы RTTI (информация о типе времени выполнения) была сохранена в классе. Он также может дать тип времени компиляции выражения или имя типа, если не указан указатель на класс с информацией о типе времени выполнения.typeof
является расширением GNU и дает вам тип любого выражения во время компиляции. Это может быть полезно, например, при объявлении временных переменных в макросах, которые могут использоваться для нескольких типов. В C ++ вместо этого вы обычно используете шаблоны .источник
typeid
будут приниматься любые выражения, а не только те, которые оценивают объекты с помощью виртуальных методов. Кроме того,typeid
примет имя типа , а не просто выражение. Вы можете сказатьtypeid(5)
или,typeid(std::string)
если хотите.typeid
может вернуть информацию о типе времени выполнения, если она доступна, но предоставит информацию о типе времени компиляции для всего остального.Отвечая на дополнительный вопрос:
В этом нет ничего плохого. То, что вы видите, является строковым представлением имени типа. Стандартный C ++ не заставляет компиляторы выдавать точное имя класса, он просто зависит от разработчика (поставщика компилятора), чтобы решить, что подходит. Короче говоря, имена зависят от компилятора.
Это два разных инструмента.
typeof
возвращает тип выражения, но оно не является стандартным. В C ++ 0x есть нечто, называемоеdecltype
AFAIK.Принимая во внимание,
typeid
что используется с полиморфными типами. Например, допустим, чтоcat
происходитanimal
:источник
typeid предоставляет тип данных во время выполнения по запросу. Typedef - это конструкция времени компиляции, которая определяет новый тип, как указано после этого. В C ++ нет typeof Вывод выглядит как (показанный в виде вписанных комментариев):
источник
Вы можете использовать Boost demangle для создания красивого названия:
и что-то вроде
источник