В стандартном заголовке typeinfo библиотеки STD имеется инструмент typeid, через который можно получать значения типов переменных или выражений в виде строки. Узнать наименование типа переменной можно через метод name() следующим образом:
#include <iostream>
#include <typeinfo>
int main()
{
short x(3);
short y(6);
std::cout << typeid(x).name() << " " << x << std::endl;
// Итоговый тип данных в выражении x + y
std::cout << typeid(x + y).name() << " " << x + y << std::endl;
return 0;
}
Результат в GCC будет:
s 3
i 9
А в MSVC результат будет другим:
short 3
int 9
То же самое справедливо и для типов, создаваемых пользователем:
#include <iostream>
#include <typeinfo>
struct Base { virtual ~Base() = default; };
struct Derived : Base {};
int main() {
Base b1;
Derived d1;
const Base *pb = &b1;
std::cout << typeid(*pb).name() << '\n';
pb = &d1;
std::cout << typeid(*pb).name() << '\n';
}
Результат в GCC:
4Base
7Derived
Результат в MSVC:
struct Base
struct Derived
Точно так же данный код будет работать на типах классов. Если структуры заменить на классы вот таким образом:
class Base {
public:
Base() {};
virtual ~Base() {};
};
class Derived : public Base {
public:
Derived() {};
virtual ~Derived() {};
};
То результат будет аналогичный.
В любом случае следует помнить, что если пользоваться typeid стандартной библиотеки STD, то итоговый код будет не кроссплатформенным. Вот такие неожиданности кроются в стандартных библиотеках, создаваемых разными вендорами.