Подтвердить что ты не робот

'typeid' в сравнении с 'typeof' в С++

Мне интересно, какая разница между typeid и typeof в С++. Вот что я знаю:

  • typeid упоминается в документации для type_info, которая определена в заголовочном файле С++ typeinfo.

  • typeof определяется в расширении GCC для 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
4b9b3361

Ответ 1

Язык С++ не имеет понятия typeof. Вы должны смотреть на некоторые расширения, специфичные для компилятора. Если вы говорите о GCC typeof, то аналогичная функция присутствует в С++ 11 через ключевое слово decltype. Опять же, С++ не имеет такого ключевого слова typeof.

typeid - это оператор языка С++, который возвращает информацию идентификации типа во время выполнения. Он в основном возвращает объект type_info, который равен равенству, сопоставимому с другими объектами type_info.

Обратите внимание, что единственным определяемым свойством возвращаемого объекта type_info является его сопоставление равным и неравномерным, т.е. объекты type_info, описывающие разные типы, должны сравнивать не равные, а объекты type_info, описывающие тот же тип должен сравнивать равный. Все остальное определяется реализацией. Методам, которые возвращают различные "имена", не гарантируется возврат каких-либо человекочитаемых и даже не гарантированных возврата вообще.

Заметим также, что вышеизложенное, вероятно, подразумевает (хотя стандарт явно не упоминает его явно), что последовательные приложения typeid для одного и того же типа могут возвращать разные объекты type_info (которые, конечно, все еще имеют для сравнения).

Ответ 2

Основное различие между ними следующее:

  • typeof является конструкцией времени компиляции и возвращает тип, определенный во время компиляции
  • typeid - это среда выполнения и, следовательно, предоставляет информацию о типе времени выполнения значения.

typeof Refenence: http://www.delorie.com/gnu/docs/gcc/gcc_36.html

typeid Rfeerence: http://en.wikipedia.org/wiki/Typeid

Ответ 3

typeid может работать во время выполнения и возвращать объект, описывающий тип времени выполнения объекта, который должен быть указателем на объект класса с виртуальными методами для RTTI (информация о типе времени выполнения) для сохранения в классе. Он также может предоставить тип времени компиляции выражения или имя типа, если не указывается указатель на класс с информацией о времени выполнения.

typeof является расширением GNU и дает вам тип любого выражения во время компиляции. Это может быть полезно, например, при объявлении временных переменных в макросах, которые могут использоваться для нескольких типов. В С++ вы обычно использовали templates.

Ответ 4

Отвечая на дополнительный вопрос:

мой следующий тестовый код для typeid не выводить правильное имя типа. что не так?

Нет ничего плохого. То, что вы видите, представляет собой строковое представление имени типа. Стандартный С++ не заставляет компиляторы испускать точное имя класса, а только разработчику (поставщику компилятора) решать, что подходит. Короче говоря, имена соответствуют компилятору.


Это два разных инструмента. typeof возвращает тип выражения, но он не является стандартным. В С++ 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.
}

Ответ 5

typeid предоставляет тип данных во время выполнения, когда его запрашивают. Typedef - это конструкция времени компиляции, которая определяет новый тип, как указано после этого. В С++ нет типаof Результат появляется как (показано как вписанные комментарии):

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

Ответ 6

Вы можете использовать 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);