Не следует недооценивать силу<BOOST_TTI_MEMBER_TYPE
>для представления типа, который может существовать или не существовать и который затем может быть впоследствии использован в других макрометафункциях, когда тип необходим в качестве параметра шаблона без возникновения ошибки компилятора. Это одна из причин, почему у нас есть два разных способа использования сгенерированной метафункции при интроспекции данных о членах, функции члена или статической функции члена замкнутого типа.
В тех случаях, когда мы определяем составной синтаксис при использовании<BOOST_TTI_HAS_MEMBER_DATA
>,<BOOST_TTI_HAS_MEMBER_FUNCTION
>или<BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION
>, подпись для данных члена, функции члена или функции статического члена представляет собой один тип. Для<BOOST_TTI_HAS_MEMBER_DATA
>подпись является указателем на данные члена, для<BOOST_TTI_HAS_MEMBER_FUNCTION
>подпись является указателем на функцию члена, а для<BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION
>подпись делится между прилагающим типом и функцией в композитном формате. Это делает синтаксическую нотацию естественной для указания, но из-за нотации мы не можем использовать функциональность вложенного типа в<BOOST_TTI_MEMBER_TYPE
>для потенциальных частей этих композитных типов. Если какая-либо часть этой подписи, которая определяет состав различных типов, является недействительной, произойдет ошибка времени компилятора.
Но в более конкретных случаях, когда мы используем<BOOST_TTI_HAS_MEMBER_DATA
>,<BOOST_TTI_HAS_MEMBER_FUNCTION
>и<BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION
>, наш составной тип в наших подписях разбивается на их отдельные типы, так что использование<BOOST_TTI_MEMBER_TYPE
>для любого из отдельных типов не приведет к ошибке времени компиляции, если указанный тип фактически не существует.
Нескольких примеров будет достаточно.
Учитывая известные типы T и U и предполагаемый тип Ntype как вложенный тип U, мы хотим выяснить, имеет ли тип T функцию члена, чья подпись<voidaMemberFunction(U::Ntype)
>.
Во-первых, используя<BOOST_TTI_HAS_MEMBER_FUNCTION
>, мы будем кодировать:
#include <boost/tti/has_member_function.hpp>
BOOST_TTI_HAS_MEMBER_FUNCTION(aMemberFunction)
has_member_function_aMemberFunction<void (T::*)(U::Ntype)>::value;
Если вложенного типа U::Ntype не существует, это приводит к ошибке компилятора. Мы действительно хотим избежать этой ситуации, поэтому давайте попробуем нашу альтернативу.
Во-вторых, используя<BOOST_TTI_HAS_MEMBER_FUNCTION
>, мы будем кодировать:
#include <boost/tti/member_type.hpp>
#include <boost/tti/has_member_function.hpp>
BOOST_TTI_HAS_MEMBER_TYPE(Ntype)
BOOST_TTI_HAS_MEMBER_FUNCTION(aMemberFunction)
typedef typename has_member_type_Ntype<U>::type OurType;
has_member_function_aMemberFunction<T,void,boost::mpl::vector<OurType> >::value;
Если вложенный тип U::Ntype действительно существует, а T имеет функцию члена, подпись которого<voidaMemberFunction(U::Ntype)
>наша «ценность» истинна, в противном случае она ложна. В этом случае мы никогда не получим ошибку компилятора.
В качестве второго примера мы снова будем использовать предположения нашего первого примера, учитывая известные типы T и U и предполагаемый тип Ntype как вложенный тип U. Но на этот раз давайте рассмотрим функцию статического члена, подпись которого<voidaStaticMemberFunction(U::Ntype)
>.
Во-первых, используя<BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION
>, мы будем кодировать:
#include <boost/tti/has_static_member_function.hpp>
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(aStaticMemberFunction)
has_static_member_function_aStaticMemberFunction<T,void (U::Ntype)>::value;
Опять же, если вложенного типа U::Ntype не существует, это приводит к ошибке компилятора, поэтому давайте попробуем нашу альтернативу.
Во-вторых, используя<BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION
>нашу конкретную форму, мы будем кодировать:
#include <boost/tti/member_type.hpp>
#include <boost/tti/has_static_member_function.hpp>
BOOST_TTI_HAS_MEMBER_TYPE(Ntype)
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(aStaticMemberFunction)
typedef typename has_member_type_Ntype<U>::type OurType;
has_static_member_function_aStaticMemberFunction<T,void,boost::mpl::vector<OurType> >::value;
Если вложенный тип U::Ntype действительно существует, а T имеет функцию члена, подпись которого<voidaMemberFunction(U::Ntype)
>наша «ценность» истинна, в противном случае она ложна. В этом случае мы никогда не получим ошибку компилятора.