Вы генерируете метафункцию, используя макрос с именем шаблона внутреннего класса:
BOOST_TTI_HAS_TEMPLATE(AClassTemplate,BOOST_PP_NIL)
BOOST_TTI_HAS_TEMPLATE(AClassTemplate)
BOOST_TTI_HAS_TEMPLATE(AClassTemplate,(2,(class,int)))
BOOST_TTI_HAS_TEMPLATE(AClassTemplate,class,int)
генерирует метафункцию под названием «has_template_AClassTemplate» в текущем объеме.
Если вы хотите интроспектировать одно и то же имя шаблона класса, используя форму<templatetype
parameters
>и форму<specificparameters
>, у вас возникнет проблема, что вы будете генерировать метафункцию с тем же именем и нарушать правило ODR C++. В этом конкретном случае вы можете использовать альтернативный макрос BOOST_TTI_TRAIT_HAS_TEMPLATE, чтобы назвать конкретную метафункцию, которая будет генерироваться.
Вы вызываете метафункцию, инстанцируя шаблон с закрытым типом для самоанализа. Возвратное значение, называемое «значением», представляет собой константу компиляции времени.
has_template_AType<Enclosing_Type>::value
Сначала мы генерируем метафункции для различных имен шаблонов внутреннего класса:
#include <boost/tti/has_template.hpp>
BOOST_TTI_HAS_TEMPLATE(Template1)
BOOST_TTI_HAS_TEMPLATE(Template2)
BOOST_TTI_HAS_TEMPLATE(Template3)
BOOST_TTI_HAS_TEMPLATE(Template4)
BOOST_TTI_HAS_TEMPLATE(Template5)
BOOST_TTI_HAS_TEMPLATE(Template1,BOOST_PP_NIL)
BOOST_TTI_HAS_TEMPLATE(Template2,BOOST_PP_NIL)
BOOST_TTI_HAS_TEMPLATE(Template3,BOOST_PP_NIL)
BOOST_TTI_HAS_TEMPLATE(Template4,BOOST_PP_NIL)
BOOST_TTI_HAS_TEMPLATE(Template5,BOOST_PP_NIL)
BOOST_TTI_HAS_TEMPLATE(Template6,class,int)
BOOST_TTI_HAS_TEMPLATE(Template7,typename,template<class,class> struct,long)
BOOST_TTI_HAS_TEMPLATE(Template8,double,typename)
BOOST_TTI_HAS_TEMPLATE(Template9,typename,class,typename,class,typename,short)
BOOST_TTI_HAS_TEMPLATE(Template6,(2,(class,int)))
BOOST_TTI_HAS_TEMPLATE(Template7,(4,(typename,template<class,class> struct,long)))
BOOST_TTI_HAS_TEMPLATE(Template8,(2,(double,typename)))
BOOST_TTI_HAS_TEMPLATE(Template9,(6,(typename,class,typename,class,typename,short)))
Давайте создадим некоторые пользовательские типы, которые мы хотим интроспектировать.
struct Top
{
template <class X> struct Template1 { };
template <typename A,typename B,typename C> class Template2 { };
template <typename A,typename B,typename C,int D> class Template3 { };
};
struct Top2
{
template <typename A,typename B,typename C,class D> class Template3 { };
template <class X,typename Y> struct Template4 { };
template <typename A,class B,typename C,class D,typename E> class Template5 { };
};
struct Top3
{
template <class X,int Y> struct Template6 { };
template <typename A,template<class,class> struct B,long C> class Template7 { };
};
struct Top4
{
template <double X,typename Y> struct Template8 { };
template <typename A,class B,typename C,class D,typename E,short F> class Template9 { };
};
Наконец, мы прибегаем к нашей метафункции и возвращаем нашу ценность. Все это происходит во время компиляции и может быть использовано программистами, выполняющими компиляцию метапрограммирования шаблона времени.
has_template_Template1<Top>::value;
has_template_Template1<Top2>::value;
has_template_Template2<Top>::value;
has_template_Template2<Top2>::value;
has_template_Template3<Top>::value;
has_template_Template3<Top2>::value;
has_template_Template4<Top>::value;
has_template_Template4<Top2>::value;
has_template_Template5<Top>::value;
has_template_Template5<Top2>::value;
has_template_Template6<Top3>::value;
has_template_Template6<Top4>::value;
has_template_Template7<Top3>::value;
has_template_Template7<Top4>::value;
has_template_Template8<Top3>::value;
has_template_Template8<Top4>::value;
has_template_Template9<Top3>::value;
has_template_Template9<Top4>::value;
Макро кодирует имя шаблона внутреннего класса, для которого мы ищем, тот факт, что мы ищем шаблон класса в закрытом типе, и необязательно параметры шаблона для этого шаблона класса.
Как только мы создадим нашу метафункцию для интроспекции шаблона внутреннего класса по имени, мы можем повторно использовать метафункцию для интроспекции любого типа, имеющего любой шаблон внутреннего класса, для этого названия.
Однако мы должны понимать, что мы ограничены в нашем повторном использовании метафункции, независимо от того, используем ли мы первоначально форму шаблона или конкретную форму. В любом случае мы всегда исследуем шаблон внутреннего класса, который соответствует этой форме. В случае формы параметров типа шаблона любой шаблон внутреннего класса, для которого мы интроспектируем, должен иметь все параметры типа шаблона, а также правильное название. В случае конкретной формы параметров любой шаблон внутреннего класса, для которого мы интроспектируем, должен иметь параметры шаблона, которые соответствуют конкретным параметрам шаблона, переданным макросу, а также правильное имя.