How to Use the typeid Operator in C++
This article explains and demonstrates how to utilize the typeid
operator in C++.
Use the typeid
Operator to Retrieve the Type Name of the Object in C++
You can use the typeid
operator to retrieve the type information of the given expression or object. It returns a reference to the std::type_info
standard-library type, which is defined in a <typeinfo>
header.
The std::type_info
object has the member function name
that you can utilize to return a character string describing the underlying type of the argument object. Note that the type information retrieved by typeid
is implementation-dependent. Namely, the most common compilers gcc
and clang
return mangled names, as demonstrated in the next code example.
Other implementations like Microsoft Visual C++ display information in more readable forms. Stil, keep in mind that you can still learn to identify the names for the built-in types displayed by the former implementation. For example, the int
object returns an i
character, and a pointer to the int
object returns a Pi
character string.
#include <iostream>
#include <string>
#include <typeinfo>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main() {
int i1 = 1234;
string str1("arbitrary string");
auto ptr = &i1;
cout << "i1 type: " << typeid(i1).name() << '\n'
<< "str1 type: " << typeid(str1).name() << '\n'
<< "ptr type: " << typeid(ptr).name() << endl;
const std::type_info& r1 = typeid(i1);
cout << '\n' << "i1 type: " << r1.name() << '\n';
return EXIT_SUCCESS;
}
Output:
i1 type: i
str1 type: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
ptr type: Pi
i1 type: i
On the other hand, if we call the typeid
command on references to objects, we will find that the retrieved type information is not always accurate and sometimes too cryptic to be readable. The following example shows such a case where the second call to the typeid
operator returns the type information incorrectly.
#include <iostream>
#include <string>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {};
struct Derived : Base {};
struct Base2 {
virtual void foo() {}
};
struct Derived2 : Base2 {};
int main() {
Derived d1;
Base& b1 = d1;
cout << "non-polymorphic base: " << typeid(b1).name() << '\n';
Derived2 d2;
Base2& b2 = d2;
cout << "polymorphic base: " << typeid(b2).name() << '\n';
return EXIT_SUCCESS;
}
Output:
non-polymorphic base: 4Base
polymorphic base: 8Derived2
This behavior can be corrected using the Boost TypeIndex library function, type_id_with_cvr
, which can return the type information accurately. Generally, objects with the const
, volatile
, &
and &&
modifiers all cause the incorrect type information when typeid
operator is used; therefore, you should better rely on the type_id_with_cvr
function.
The following code example requires the Boost library to be installed on the system, and the type_id_with_cvr
function is under the boost::typeindex
namespace.
#include <boost/type_index.hpp>
#include <iostream>
#include <string>
#include <typeinfo>
using boost::typeindex::type_id_with_cvr;
using std::cout;
using std::endl;
struct Base {};
struct Derived : Base {};
struct Base2 {
virtual void foo() {}
};
struct Derived2 : Base2 {};
int main() {
Derived d1;
Base& b1 = d1;
Derived2 d2;
Base2& b2 = d2;
cout << type_id_with_cvr<decltype(b1)>().pretty_name() << '\n';
cout << type_id_with_cvr<decltype(b2)>().pretty_name() << '\n';
return EXIT_SUCCESS;
}
Output:
Base&
Base2&
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook