Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 | страница 32
>y
, дает объект >std: :type_info
, а он имеет функцию-член >name
, которая дает С-строку (т.е. >const char*
), представляющую имя типа.Не гарантируется, что вызов >std::type_info::name
вернет что-то разумное, но его реализации изо всех сил пытаются быть полезными. Уровень этой полезности варьируется от компилятора к компилятору. Компиляторы GNU и Clang, например, сообщают, что тип >x
— это “>i
” а тип >y
— “>PKi
”. Эти результаты имеют смысл, если вы будете знать, что “>i
” у данных компиляторов означает “>int
”, а “>PK
” — “указатель на константу”.
(Оба компилятора поддерживают инструмент >c++filt
, который расшифровывает эти имена.) Компилятор Microsoft генерирует менее зашифрованный вывод: “>int
” для >x
и “i>nt const *
”для >y
.
Поскольку это корректные результаты для типов >x
и >y
, вы можете подумать, что задача получения информации о типах решена, но не делайте скоропалительных выводов. Рассмотрим более сложный пример:
>template
>void f(const T& param); // вызываемая далее
>std::vector
>const auto vw = createVec(); // Инициализация vw возвратом
> // фабричной функции
>if (!vw.empty()) {
> f(&vw[0]); // Вызов f
>}
Этот код, включающий пользовательский тип (>Widget
), контейнер STL (>std::vector
) и переменную auto (>vw
), является более представительным и интересным примером. Было бы неплохо узнать, какие типы выводятся для параметра типа шаблона >Т
и для параметра param функции >f
.
Воспользоваться >typeid
в этой задаче достаточно просто. Надо всего лишь добавить немного кода в функцию f для вывода интересующих нас типов:
>template
>void f(const T& param) {
> using std::cout;
> // Вывод в поток cout типа T:
> cout << "Т = " << typeid(T).name() << '\n';
> // Вывод в поток cout типа param:
> cout << "param = " << typeid(param).name() << '\n';
>}
Выполнимые файлы, полученные с помощью компиляторов GNU и Clang, дают следующий результат:
>Т = PK6Widget
>param = PK6Widget
Мы уже знаем, что в этих компиляторах >PK
означает указатель на константу, так что вся загадка — в цифре >6
. Это просто количество символов в следующем за ней имени класса (>Widget
). Таким образом, данные компиляторы сообщают нам, что и >Т
, и >param
имеют один и тот же тип — >const Widget*
. Компилятор Microsoft согласен:
>Т = class Widget const *
>param = class Widget const *
Три независимых компилятора дают одну и ту же информацию, что свидетельствует о том, что эта информация является точной. Но давайте посмотрим более внимательно. В шаблоне