C++中的“typeid”与“typeof”

pgvzfuti  于 2023-01-14  发布在  其他
关注(0)|答案(7)|浏览(493)

我想知道typeidtypeof在C++中有什么区别。下面是我所知道的:

  • typeidtype_info的文档中提到,该文档在C++头文件typeinfo中定义。
  • typeof在C的GCC扩展和C++ Boost库中定义。

另外,这是我创建的测试代码test,我发现typeid没有返回我期望的结果,为什么?

主.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
lndjwyie

lndjwyie1#

C++ 没有typeof这样的东西。你一定在寻找一些编译器特定的扩展。如果你在谈论GCC的typeof,那么类似的特性通过关键字decltype出现在C11中。同样,C没有这样的typeof关键字。
typeid是一个 C++ 运算符,在运行时返回类型标识信息,它基本上返回一个type_info对象,该对象与其他type_info对象具有等价性。
注意,返回的type_info对象的唯一定义的属性是它是相等和不相等可比较的,即,描述不同类型的type_info对象将比较不相等,而描述相同类型的type_info对象必须比较相等。其它一切都是实现定义的。返回各种“名称”的方法不保证返回任何人类可读的东西,甚至根本不保证能归还任何东西。
还要注意的是,上面可能暗示(尽管标准似乎没有明确提到),将typeid连续应用于同一类型可能返回不同的type_info对象(当然,仍然必须比较相等)。

dfty9e19

dfty9e192#

两者之间的主要区别如下

  • typeof是编译时构造,返回编译时定义的类型
  • typeid是一个运行时构造,因此提供了关于值的运行时类型的信息。

参考类型:http://www.delorie.com/gnu/docs/gcc/gcc_36.html
typeid参考:https://en.wikipedia.org/wiki/Typeid

pgx2nnw8

pgx2nnw83#

typeid可以在运行时操作,并返回一个描述对象的运行时类型的对象,该对象必须是一个指向具有虚方法的类的对象的指针,以便将RTTI (run-time type information)存储在该类中。如果未指定指向具有运行时类型信息的类的指针,则它还可以给予表达式的编译时类型或类型名称。
typeof是一个GNU扩展,它在编译时给你任何表达式的类型。例如,在宏中声明可能用于多种类型的临时变量时,这会很有用。在C++中,你通常会使用templates来代替。

afdcj2ne

afdcj2ne4#

回答附加问题:
我下面的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.
}
ubbxdtey

ubbxdtey5#

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
plupiseo

plupiseo6#

您可以使用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);
mccptt67

mccptt677#

尽管正如前面的评论者所指出的,在C++中没有typeof这样的东西,但是你可以利用函数重载来创建一个伪typeof函数:

const char *type_of(int x){return “int”;}
const char *type_of(const char *x){return “const char*”;}

当然,这也可以扩展到使用其他数据类型,我是C++新手,所以可能会有一些问题,比如运行时的错误,但是在我使用模板参数和从浮点型中区分整型的用例中,比如说,是很简单的。
优化:对于重载函数来说,为了提高内存效率,返回一个short而不是const char * 可能会更好,然后可以将其与另一个short进行比较,或者插入到哈希表中以获得字符串表示。

相关问题