typeid keyword

Introduced in CS247, when introducing the Liskov Substitution Principle.

Resources

std::string mystr = "string";
std::cout << "myint has type: " << typeid(myint).name() << '\n'

how does typeid work under the hood?

  • For non-polymorphic types (identified by the virtual functions), it will get the static type
  • For Polymorphic Type, it will get the dynamic type

Example

class Base {}; // non-polymorphic
class Derived : public Base {};
 
class Base2 {  // polymorphic type
    virtual void foo() {};
};
class Derived2 : public Base2 {};
 
int main() {
    int x = 5;
    std::cout << "integer has type name: " << typeid(x).name() << std::endl;  // i
    int* int_p = &x;
    std::cout << "integer pointer has name: " << typeid(int_p).name() << std::endl;  // Pi
    Base* b = new Derived{};
    std::cout << typeid(*b).name() << std::endl;  // 4Base
    Base2* c = new Derived2{};
    std::cout << typeid(*c).name() << std::endl;  // 8Derived2
    std::cout << typeid(c).name() << std::endl;   // P5Base2

If you just printed the pointer type, it would always return PBase

Since you’re asking for the type of the pointer itself, not what it points to, it will always print the static type: Base2*.

typeid operator strips const and volatile, i.e.:

const int y = 5;
std::cout << typeid(y).name() << std::endl; // i

If you wanted to check for whether it was a const it, you can do it with the std::is_same.

CS247

bool Circle::operator==(const Shape& other) const {
	if (typeid(other) != typeid(Circle)) return false;
	const Circle& cother=static_cast<const Circle&>(other);
	...
}

typeidreturnsstd::type_info` objects that can be compared.

Difference between typeid and dynamic_cast?

  • typeid: Is other exactly a Circle? Doesn’t consider inheritance.
  • dynamic_cast: Is other a Circle, or a subclass of Circle? Considers inheritance.

typeid uses the dynamic-type so long as the class has at least one virtual method.