Skip to content

typeid

wikipedia Run-time type information#typeid

cppreference typeid operator

Queries information of a type.

Used where the dynamic type of a polymorphic object must be known and for static type identification.

Notes

When applied to an expression of polymorphic type, evaluation of a typeid expression may involve runtime overhead (a virtual table lookup), otherwise typeid expression is resolved at compile time.

NOTE:

关于 polymorphic type,参见 C++\Language-reference\Basic-concept\Type-system\Type-system\OOP-class-type 章节;

对于 polymorphic typetypeid expression是evaluated at runtime的,因为它是有dynamic type的;

对于 non-polymorphic typetypeid expression是evaluated at compile time的,因为它没有dynamic type,只有static type;

上述是typeid的实现细节,可以看到compiler是会充分进行optimize的,显然它是compiler的optimize principle。

在下面的 "Example: typeid(*this)" 段中,列举的例子是对上述的说明。

There is no guarantee that the same std::type_info instance will be referred to by all evaluations of the typeid expression on the same type, although std::type_info::hash_code of those type_info objects would be identical, as would be their std::type_index.

#include <string>
#include <iostream>
#include <typeinfo>
#include <typeindex>
#include <assert.h>     /* assert */
class A
{
};

int main()
{
    const std::type_info &ti1 = typeid(A);
    const std::type_info &ti2 = typeid(A);

    assert(&ti1 == &ti2); // not guaranteed
    assert(ti1.hash_code() == ti2.hash_code()); // guaranteed
    assert(std::type_index(ti1) == std::type_index(ti2)); // guaranteed
}
// g++ --std=c++11 test.cpp

Example: typeid(*this)

下面是例子( 源自 thegreenplace A polyglot's guide to multiple dispatch ):

Polymorphic type

#include <string>
#include <iostream>
#include <typeinfo>
#include <memory>
class Shape
{
public:
    virtual std::string name() const
    {
        return typeid(*this).name();
    }
};
class Rectangle: public Shape
{
};

class Ellipse: public Shape
{

};

int main()
{
    std::unique_ptr<Shape> pr1(new Rectangle);
    std::unique_ptr<Shape> pr2(new Rectangle);
    std::unique_ptr<Shape> pe(new Ellipse);

    std::cout << pr1->name() << std::endl;
    std::cout << pr2->name() << std::endl;
    std::cout << pe->name() << std::endl;
}
// g++ --std=c++11 test.cpp

输出如下:

9Rectangle
9Rectangle
7Ellipse

显然typeid(*this)是evaluated at runtime的,因此Shape是polymorphic type,它有dynamic type,所以typeid(*this)取到的是dynamic type;

Non-polymorphic type

#include <string>
#include <iostream>
#include <typeinfo>
#include <memory>
class Shape
{
public:
    std::string name() const
    {
        return typeid(*this).name();
    }
};
class Rectangle: public Shape
{
};

class Ellipse: public Shape
{

};



int main()
{
    std::unique_ptr<Shape> pr1(new Rectangle);
    std::unique_ptr<Shape> pr2(new Rectangle);
    std::unique_ptr<Shape> pe(new Ellipse);

    std::cout << pr1->name() << std::endl;
    std::cout << pr2->name() << std::endl;
    std::cout << pe->name() << std::endl;
}
// g++ --std=c++11 test.cpp

输出如下:

5Shape
5Shape
5Shape

显然typeid(*this)是evaluated at compile time的,因此Shape是non-polymorphic type,它没有dynamic type,所以typeid(*this)取到的是static type;

Polymorphic type

#include <string>
#include <iostream>
#include <typeinfo>
#include <memory>
class Shape
{
public:
    std::string name() const
    {
        return typeid(*this).name();
    }
    virtual void test()
    {

    }
};
class Rectangle: public Shape
{
};

class Ellipse: public Shape
{

};



int main()
{
    std::unique_ptr<Shape> pr1(new Rectangle);
    std::unique_ptr<Shape> pr2(new Rectangle);
    std::unique_ptr<Shape> pe(new Ellipse);

    std::cout << pr1->name() << std::endl;
    std::cout << pr2->name() << std::endl;
    std::cout << pe->name() << std::endl;
}
// g++ --std=c++11 test.cpp

输出如下:

9Rectangle
9Rectangle
7Ellipse

显然typeid(*this)是evaluated at runtime的,因此Shape是polymorphic type,它有dynamic type,所以typeid(*this)取到的是dynamic type;

typeid(*this)的用法是值得借鉴的。