Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 | страница 33
>const Т&
. В таком случае не кажется ли вам странным, что и >Т
, и >param
имеют один и тот же тип? Если тип >Т
, например, представляет собой >int
, то типом >param
должен быть >const int&
— совершенно другой тип.К сожалению, результат >std::type_info::name
ненадежен. Например, в данном случае тип, который все три компилятора приписывают >param
, является неверным. Кроме того, он по сути обязан быть неверным, так как спецификация >std::type_info::name
разрешает, чтобы тип рассматривался как если бы он был передан в шаблонную функцию по значению. Как поясняется в разделе 1.1, это означает, что если тип является ссылкой, его “ссылочность” игнорируется, а если тип после удаления ссылочности оказывается >const
(или >volatile
), то соответствующие модификаторы также игнорируются. Вот почему информация о типе >param
— который на самом деле представляет собой >const Widget* const&
— выводится как >const Widget*
. Сначала удаляется ссылочность, а затем у получившегося указателя удаляется константность.
Не менее печально, что информация о типе, выводимая редакторами IDE, также ненадежна — или как минимум ненадежно полезна. Для этого же примера мой редактор IDE сообщает о типе >Т
как (я не придумываю!):
>const
>std::_Simple_types
>std::allocator
Тот же редактор IDE показывает, что тип param следующий:
>const std::_Simple_types<...>::value_type *const &
Это выглядит менее страшно, чем тип >Т
, но троеточие в средине типа сбивает с толку, пока вы не поймете, что это редактор IDE попытался сказать “Я опускаю все, что является частью типа T”. Ваша среда разработки, быть может, работает лучше моей — если вы достаточно везучий.
Если вы склонны полагаться на библиотеки больше, чем на удачу, то будете рады узнать, что там, где >std::type_info::name
и IDE могут ошибаться, библиотека Boost TypeIndex (часто именуемая как Boost.TypeIndex) приведет к успеху. Эта библиотека не является частью стандарта С++, но точно так же частью стандарта не являются ни IDE, ни шаблоны наподобие рассмотренного выше TD. Кроме того, тот факт, что библиотеки Boost (доступные по адресу >boost.org
) являются кроссплатформенными, с открытым исходным кодом и с лицензией, разработанной так, чтобы быть приемлемой даже для самых параноидальных юристов, означает, что код с применением библиотек Boost переносим практически так же хорошо, как и код, основанный на стандартной библиотеке.