芪æãªããããããã¢ã³ïŒ
ãã®èšäºã§ã¯ãC ++ã§
ã³ã³ãã€ã«æããŒã¿ ïŒåïŒ
ãã©ã³ã¿ã€ã ããŒã¿ ïŒæŽæ°å€ïŒã«
ããŸãã¯ãã®éã« å€æããæ¹æ³ã«ã€ããŠèª¬æããŸãã
äŸïŒ
int nType = ... ;
if ïŒ boost :: is_base_of < ISettableã / * ... nTypeã«ãã£ãŠé ãããåãããã§éæ³ã®ããã«è§£æ±ºããŸã... * / > :: value ïŒ
{
//äœãããã
}
ä»ã«
{
//å¥ã®ããšããã
}
ãã®ãããã¯å
šäœã¯ããnTypeã«ãã£ãŠé ãããåãããã§éæ³ã®ããã«è§£æ±ºãããã®ã§ã¯ãªããäœãæžãå¿
èŠãããããç解ããããšãç®çãšããŠããŸãã
çµæã«ã®ã¿èå³ãããå Žåã¯ãæåŸã®ã»ã¯ã·ã§ã³ãŸã§ã¹ãããããŠãã ããã
ã¡ãã£ãšããæŽå²
ããã¯ãã¹ãŠãåœçªã§ã¯ãã»ãŒæ¬¡ã®ããã«åäœãããªããžã§ã¯ãã®è€éãªå·¥å Žã§äœæ¥ããå¿
èŠããããšããäºå®ããå§ãŸããŸããïŒãªããžã§ã¯ããäœæããã«ã¯ãåçããŒã¿ã®æ·±byã«åºã¥ããŠãäœæããããªããžã§ã¯ãã®ã¿ã€ãã®IDãè¿ãç¹å®ã®é¢æ°ãåŒã³åºãããŸãã ãã®IDã¯ã¹ã€ããã±ãŒã¹ã«åé¡ãããå®éã«æ¬¡ã®ãããªå¿
èŠãªãªããžã§ã¯ããäœæãããŸãã
int nObjectType = ResolveObjectType ïŒ ... ïŒ ;
boost :: shared_ptr < IObject > pObject = CreateObject ïŒ nObjectType ïŒ ;
ç¹å®ã®ã©ã³ã¿ã€ã æ¡ä»¶äžã§ããã©ãŒã ã®ã©ãããŒãããã€ãã®ãªããžã§ã¯ãã«æããå¿
èŠãããããšãå€æãããŸã§ããã®ã·ã¹ãã ã§ã¯ãã¹ãŠãããŸããããŸããã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
ã¯ã©ã¹ CFilter ïŒ ãããªã㯠TObject
{
ä»®æ³ ããŒã« FilterValue ïŒ ... ïŒ { ... } ;
} ;
ãã®ãããªã©ãããŒã¯ãç¹å®ã®æ¡ä»¶äžã§å¿
èŠãªç¹å®ã®æ°ããæ©èœããªããžã§ã¯ãã«è¿œå ããŸããã åœç¶ãæåã¯åžžã«ãã¹ãŠã®ã¿ã€ãã®ãªããžã§ã¯ãã«æ¯ã¹ãŠãã©ãããŒã¯åžžã«å°ãã ããã³ã°ããå°ãã ããã³ã°ããŠããŸããïŒãã®ãããã»ãã®æ°è¡ã®ã³ãŒããè¿œå ããå¿
èŠããããŸããããéåžžã«ç°¡åã§ããïŒã ãã ããäžå¿
èŠãªã©ãããŒã¯ãäœæ¥ã®ããžãã¯ã«å®³ãäžããããšã¯ãããŸãããããªããžã§ã¯ãã®ãµã€ãºã倧ããããŸãããããã¯åãå
¥ããããŸããã§ããããã¡ã¯ããªãŒèªäœãšãã®å©ããåããŠäœæããããªããžã§ã¯ãã¯ãããã©ãŒãã³ã¹ãšã¡ã¢ãªæ¶è²»ã®ç¹ã§éèŠã§ããã
ãããã£ãŠãã©ãããŒããªãã·ã§ã³ã§å«ããå¿
èŠããããŸããã ããã«åé¡ãçºçããŸããïŒ
ãã®ãã¹ãŠãå®çŸããç§ã¯åº§ã£ãŠèããŸããã ããã«ãGetObjectTypeïŒ...ïŒã«ãã£ãŠè¿ãããå€ã®èåŸã«é ãããŠããåãæç»ããæ¹æ³ãåŠç¿ããã ãã§ãã³ã³ãã€ã©ãŒã«ãšã£ãŠæ確ã«ãªãããã«ãªããŸãããã€ãŸãã 粟ç¥ã§ç©äºãæžãããšãã§ããããã«ïŒ
int nType = ... ;
if ïŒ boost :: is_base_of < ISettableã / * ... nTypeã«ãã£ãŠé ãããåãããã§éæ³ã®ããã«è§£æ±ºããŸã... * / > :: value ïŒ
{
//äœãããã
}
ä»ã«
{
//å¥ã®ããšããã
}
ç§ã®æåã®èãïŒãããã¯äžå¯èœã§ãïŒã
ãã³ãã¬ãŒãã®éæ³ããŸãã¯äžå¯èœã¯å¯èœã§ãïŒ
ããå°ãèããåŸã次ã®2ã€ã®é¢æ°ãèšè¿°ããã ãã§ãããšããçµè«ã«éããŸããã
//ïŒ TObjectã«å¯Ÿå¿ãããªããžã§ã¯ãã¿ã€ãèšè¿°åãè¿ããŸãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
ã€ã³ã©ã€ã³ int MakeDescriptor ïŒ ïŒ ;
//ïŒ nullptrãæå®ããŠrcFunctorãåŒã³åºããnTypeDescriptorã«ãã£ãŠé ãããå®éã®ãªããžã§ã¯ãã¿ã€ããåŒã³åºããŸãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TFunctor >
ã€ã³ã©ã€ã³ ã¿ã€ãåImpl :: ResolveReturnType < TFunctor > :: ã¿ã€ã CallWithType ïŒ const TFunctor ïŒ rcFunctorã int nTypeDescriptor ïŒ ;
ããã§ã¯ãã¹ãŠãæ確ã§ãïŒ
- æåã®é¢æ°ã¯ããªããžã§ã¯ãã®ã¿ã€ãïŒãã³ãã¬ãŒããã©ã¡ãŒã¿ãŒïŒã«å¿ããŠããªããžã§ã¯ãã¿ã€ãèšè¿°åïŒæ°å€ïŒãè¿ããŸãã
- 2çªç®ã®é¢æ°ã¯ãæž¡ããããã¡ã³ã¯ã¿ãŒãåŒã³åºãããã©ã¡ãŒã¿ãŒãšããŠæ°å€nTypeDescriptorå
ã§ãšã³ã³ãŒãããããªããžã§ã¯ãã®ã¿ã€ããžã®ãã€ã³ã¿ãŒã䜿çšããŸãã ãããã£ãŠããã¡ã³ã¯ã¿ãŒã§ãã³ãã¬ãŒãæŒç®åïŒïŒã䜿çšãããšãå
ã®åãå®å
šã«åŸ©å
ã§ããŸãã
ãã®æ¹æ³ã§äœ¿çšã§ããŸãïŒãã®äŸã§ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ããã®èšè¿°åã«ãã£ãŠãšã³ã³ãŒããããåãç¶æ¿ããããã©ãããå€æããŸãïŒã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TKind >
struct IsKindOfHelper
{
typedef bool
R ;
ã€ã³ã©ã€ã³ ããŒã«æŒç®åïŒ ïŒ ïŒ ... ïŒ const
{
falseã è¿ã ãŸã ã
}
ã€ã³ã©ã€ã³ ããŒã«æŒç®åïŒ ïŒ ïŒ TKind * ïŒ const
{
trueã è¿ã ãŸã ã
}
} ;
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
ã€ã³ã©ã€ã³ bool IsKindOf ïŒ int nTypeDescriptor ïŒ
{
Return CallWithType ïŒ IsKindOfHelper < TObject > ïŒ ïŒ ãnTypeDescriptor ïŒ ;
}
...
int nType = ... ;
if ïŒ IsKindOf < ISettable > ïŒ nType ïŒ ïŒ
{
//äœãããã
}
ä»ã«
{
//å¥ã®ããšããã
}
ã¿ã€ããªã¹ããšèšè¿°åã
ããã§ã¯ãå®è£
ã«åãââããããŸãããã ãŸããã¿ã€ããšã¿ã€ãã®èšè¿°åã«äžèŽããã³ã³ãã€ã«ã¿ã€ã ããŒãã«ãå¿
èŠã§ãã ããã§æãç°¡åãªãªãã·ã§ã³ã¯Loki :: Typelistã§ããããã¯æ¬¡ã®åœ¢åŒã®æ§é ã§ãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ Tã ã¯ã©ã¹ U >
struct typelist
{
typedef Tããã;
typedef U Tail ;
} ;
ãã€ãŠãã®æ§é ãçèããããšã§ãC ++ã«ã€ããŠã®èããå®å
šã«éããŸã«ãªããŸããã ãªãå¿
èŠãªã®ãèŠãŠã¿ãŸãããã ãã¹ãŠãéåžžã«ç°¡åã§ãïŒä»»æã®é·ãã®ã¿ã€ãã®ãã«ããªã¹ããèšå®ãããŠããŸãïŒ
typedef Loki :: Typelist < int ãLoki :: Typelist < char ãLoki :: Typelist < void ãLoki :: NullType >>>
TMyList ;
ããã§ã¯ã3ã€ã®èŠçŽ ã®åã®ãªã¹ããæå®ãããŠããŸãïŒintãcharãvoidã Loki :: NullTypeã¯ãªã¹ãã®çµãããæå³ããŸãã ãã®ãªã¹ãããç¹å¥ãªã¡ã¿é¢æ°ã䜿çšããŠãã¿ã€ãã€ã³ããã¯ã¹ãšã€ã³ããã¯ã¹ã«ããã¿ã€ããæœåºã§ããŸãã
// int MyInt;
Loki :: TypeAt < TMyListã 0 > :: Result MyInt ;
// char MyChar;
Loki :: TypeAt < TMyListã 1 > :: Result MyChar ;
int nIndexOfChar = Loki :: IndexOf < TMyListã char > :: value ;
ãããã®ã¡ã¿é¢æ°ã¯ãã¹ãŠãã³ã³ãã€ã«æ®µéã§ãåŒã³åºããããå®è¡æéã®ãªãŒããŒããããå¿
èŠãšããŸããã Lokiã®è©³çŽ°ã«ã€ããŠã¯ã
Wikipediaãåç
§ããŠãã ãããã©ã€ãã©ãªãœãŒã¹ãžã®ãªã³ã¯ããããŸãã
ãModern Design in C ++ãïŒAlexandrescuïŒã®æ¬ã§ã¯ããã¹ãŠãã©ã®ããã«æ©èœããããç¥ãããšãã§ããŸãã
å®éã«ã¯ã
Boost MPLã©ã€ãã©ãªãŒã䜿çšããŸããã ããã¯ããè€éã§ããããã®å¯èœæ§ã¯ã¯ããã«åºãã§ãã å®éšã«ãããã³ã³ãã€ã©ã¯çŽ2000çš®é¡ã®ãªããžã§ã¯ãã«èããããšã瀺ããããã®åŸã次ã®å³ã芳å¯ãããŸãã
åãªã¹ããä»ãããã¿ãŒã³ã®å®è£
ã
ã¢ã€ãã¢ïŒ
ç¹å®ã®ã¿ã€ããªã¹ãå
ã®ãã¹ãŠã®æ¢ç¥ã®ãªããžã§ã¯ãã¿ã€ãããªã¹ãããŸãã 次ã«ãç¹å®ã®åã®ã€ã³ããã¯ã¹ã¯åèšè¿°åã«ãªããŸãããåèšè¿°åãç¥ã£ãŠããå Žåã¯ããªã¹ãã§ãããèŠããšåèªäœã衚瀺ã§ããŸãã å¯äžã®åé¡ã¯æ¬¡ã®ãšããã§ããã€ã³ããã¯ã¹ã«ããåæšè«ã®å Žåãã€ã³ããã¯ã¹ã¯å®æ°ïŒã³ã³ãã€ã«æã®å€ïŒãšããŠè¡šçŸããå¿
èŠããããŸãã æ°å€å€æ°ã®å€ããmpl :: int_ <ïŒvalueïŒ>ãšãã圢åŒã®å¯Ÿå¿ããåã«å€æããæ¹æ³ãåŠç¿ããå¿
èŠããããŸãã
åå空éã®ããŒã¹ãã䜿çšã ãŸã ã
åå空é Impl
{
//ïŒ æ¢ç¥ã®ãªããžã§ã¯ãã¿ã€ãã®ãªã¹ãã
/ **çŸå®ã®äžçã§ã¯ããã®æ§é ã¯ãã³ãã¬ãŒãã«ãã£ãŠæ§ç¯ãããŠããŸãã * /
typedef mpl :: ãªã¹ã < TObjectType1ãTObjectType2ãTObjectType3 >
TKnownObjectTypes ;
//ïŒ æ¢ç¥ã®ãªããžã§ã¯ãã¿ã€ãã®æ°ã
typedef mpl :: ãµã€ãº < TKnownAtomTypes > :: ã¿ã€ã
TKnownObjectTypesCount ;
}
åå空é Impl
{
//ïŒ ãã®ã¡ã¿é¢æ°ã¯ãTKnownObjectsããTObjectã®ã€ã³ããã¯ã¹ãè¿ããŸãã
/ ** TObjectãTKnownObjectsã«ååšããªãå Žåã-1ãè¿ããŸã* /
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
struct MakeDescriptorImpl
ïŒ / * if * / mpl :: eval_if <
/ *ïŒTObjectïŒãèŠã€ãã== end * /
is_same <
typename mpl :: find < TKnownObjectTypesãTObject > :: type ã
mpl :: end < TKnownObjectTypes > :: ã¿ã€ã > ã
/ * -1ãè¿ããŸã* /
mpl :: identity < mpl :: int_ < -1 >> ã
/ *ãã®ä»ã®è·é¢ãè¿ãïŒéå§ãæ€çŽ¢ïŒTObjectïŒïŒ* /
mpl :: é©çš <
mpl :: è·é¢ <
mpl :: begin < TKnownObjectTypes > :: type ã
mpl :: find < TKnownObjectTypesã_ >> ã
TObject >> :: ã¿ã€ã
{
} ;
//ïŒ TObjectTypeã§TFunctorãåŒã³åºãã®ã«åœ¹ç«ã¡ãŸã*
ãã³ãã¬ãŒã < ã¯ã©ã¹ TFunctor >
struct CallWithObjectTypeHelperPointerBased
{
å
¬é ïŒ
// typename ResolveReturnType <TFunctor> :: TFunctorã«è©äŸ¡ãããå:: R if
// TFunctor :: R typedefãååšããŸãããã以å€ã®å Žåã¯ãvoidã«è©äŸ¡ãããŸãã
typedef typename ResolveReturnType < TFunctor > :: ã¿ã€ã
R ;
ä¿è·ããã ïŒ
const TFunctor ïŒ
m_rcFunctor ;
å
¬é ïŒ
CallWithObjectTypeHelperPointerBased ïŒ const TFunctor ïŒ rcFunctor ïŒ
ïŒ m_rcFunctor ïŒ rcFunctor ïŒ
{
}
//ïŒ ãã®é¢æ°ã¯ãCallWithIntïŒ...ïŒã«ãã£ãŠåŒã³åºãããŸãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TIndex >
RæŒç®åïŒ ïŒ ïŒ TIndex ïŒ const
{
//ã€ã³ããã¯ã¹ã§ãªããžã§ã¯ãã¿ã€ããæ€çŽ¢
typedef typename mpl :: < TKnownObjectTypesãTIndex > :: ã¿ã€ã
TObject ;
//å®éã®ãªããžã§ã¯ãåãžã®ãã€ã³ã¿ã§ãã¡ã³ã¯ã¿ãŒãåŒã³åºããŸã
return m_rcFunctor ïŒ ïŒ TObject * ïŒ NULL ïŒ ;
}
//ïŒ ãã®é¢æ°ã¯ãCallWithIntïŒ...ïŒã«ãã£ãŠåŒã³åºãããŸãã
RæŒç®åïŒ ïŒ ïŒ mpl :: void_ ïŒ const
{
//èšè¿°åãå£ããŠããŸããç¹å¥ãªå€ã§ãã¡ã³ã¯ã¿ãŒãåŒã³åºããŸã
return m_rcFunctor ïŒ mpl :: void_ ïŒ ïŒ ïŒ ;
}
} ;
}
//ïŒ TObjectã«å¯Ÿå¿ãããªããžã§ã¯ãã¿ã€ãèšè¿°åãè¿ããŸãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
ã€ã³ã©ã€ã³ int MakeDescriptor ïŒ ïŒ
{
//äžæãªãªããžã§ã¯ãã¿ã€ãã®ãªããžã§ã¯ãã¿ã€ãã¿ã€ãã®èšè¿°ãè©Šã¿ãŸãïŒ
BOOST_STATIC_ASSERT ïŒ Impl :: MakeDescriptorImpl < TObject > :: value ïŒ = - 1 ïŒ ;
//èšè¿°åãè¿ããŸããããã¯å®éã«ã¯ã³ã³ãã€ã«æã«çæãããå®æ°ã§ãã
return Impl :: MakeDescriptorImpl < TObject > :: value ;
}
//ïŒ nObjectTypeDescriptorã«å¯Ÿå¿ããTObject *ã§rcFunctorãåŒã³åºããŸãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TFunctor >
ã€ã³ã©ã€ã³ ã¿ã€ãåImpl :: ResolveReturnType < TFunctor > :: ã¿ã€ã CallWithType ïŒ const TFunctor ïŒ rcFunctorã int nObjectTypeDescriptor ïŒ
{
// intã§åŒã³åºããŸã
// Impl :: CallWithObjectTypeHelperPointerBased <TFunctor>ïŒrcFunctorïŒ
// mplãæã€ãã¡ã³ã¯ã¿ãŒ:: int_ <N>ïŒïŒåŒæ°ãNã¯ã³ã³ãã€ã«æå®æ°
// nObjectTypeDescriptorã®å€ã«å¯Ÿå¿ã
// nObjectTypeDescriptor <0ã®å Žå|| nObjectTypeDescriptor> = TKnownObjectTypesCount
// mpl :: void_ïŒïŒã§ãã¡ã³ã¯ã¿ãŒãåŒã³åºãããã¿ã€ãèšè¿°åãå£ããŠããããšã瀺ããŸãã
return Impl :: CallWithInt < mpl :: int_ < 0 > ãTKnownObjectTypesCount > ïŒ
Impl :: CallWithObjectTypeHelperPointerBased < TFunctor > ïŒ rcFunctor ïŒ ã
nObjectTypeDescriptor ïŒ ;
}
ã³ãŒãå
šäœã«ã€ããŠè©³çŽ°ã«ã³ã¡ã³ãããããšããŸãããããŸã ããªãè€éãªã®ã§ãã³ã¡ã³ããããã€ããããŸãã
1ã
typename ResolveReturnType :: typeã¯ãã³ã³ãã€ã©ã«ãã£ãŠTFunctor :: RãšããŠè§£éãããŸãã TFunctor :: Rãç¡å¹ãªåŒã§ããå ŽåïŒããšãã°ãRåã®å®çŸ©ãTFunctorã«ãªãå ŽåïŒãtypename ResolveReturnType :: typeã¯voidãšè§£éãããŸãã
ã¯ããå¯èœã§ãã ããããç§ã¯åãã€ããŠããŸãã ã å®è£
ã¯ãCallWithIntã®å®è£
ã説æãããªã³ã¯ã®äžã«è¡šç€ºã§ããŸãã
2ã
MakeDescriptorImplã¯
boost :: mplã§ç©æ¥µçã«åäœããåšå§çã«èŠããŸãã ããããããããããã«ãã³ã¡ã³ãã«ã¯stlã«åæ§ã®åŒãå«ãŸããŠããŸãïŒãã¡ãããã³ã³ãã€ã«æ®µéã§ã¯é©çšãããŸããïŒã ã€ã³ãã³ãã¹ã¿ã€ã«ã¯
SchemeããåŒãè£ãã
ãŸã ã é¢æ°åããã°ã©ãã³ã°èšèªã«ç²ŸéããŠãã人ã¯ãC ++ã§ã®ã¡ã¿ããã°ã©ãã³ã°ïŒãã³ãã¬ãŒãããžãã¯ïŒãé¢æ°åèšèªã§ããããšãç解ããå¿
èŠããããŸãã
3ã
CallWithIntã¯ãæå¹ãªå€ã®ç¹å®ã®é åããå®è¡ææŽæ°å€ãã³ã³ãã€ã«ææŽæ°å€ã«å€æããŸãã ãã®é¢æ°ã¯å°ãåŸã§å®è£
ããŸãã
äŸïŒ42ã¯mpl :: int_ <42>ã«å€æãããŸã
4ã
mpl :: listã䜿çšãã代ããã«ãã€ããªããªãŒã䜿çšãããšãå®è£
ã¯ïŒã³ã³ãã€ã«é床ã®ç¹ã§ïŒããå¹ççã«ãªããŸãã æ®å¿µãªããããã®ãããªæ§é ã¯èŠã€ãããŸããã§ããããç§èªèº«ã¯é·ãéæžããŸããã ç§ãã¡ã®ãããžã§ã¯ãã§ã¯ãããã¯éèŠã§ã¯ãªãã500æªæºã®ã¿ã€ãã®æ°ããã®ããã«æ©èœããŸãã
5ã
å®è¡æã®ããã©ãŒãã³ã¹ã®èŠ³ç¹ããããã®ã³ãŒãã¯
éåžžã«é«éã§ãã CallWithIntã¯ã以äžã§èª¬æããããã«ãå
¥ãåã«ãªã£ãã¹ã€ããã±ãŒã¹ã§æ©èœãããããæ°å€ãåã«å€æããã«ã¯ããªãã»ããä»ãã®ç¡æ¡ä»¶ãžã£ã³ããæ°åè¡ãã ãã§æžã¿ãŸãã éå€æã®å Žåãäœãå¿
èŠãããŸããã MakeDescriptorã¯å®æ°ã«ã€ã³ã©ã€ã³åããŸãã
6ã
å®äžçã§ã¯ãæ¢ç¥ã®ãªããžã§ã¯ãã®ãªã¹ãã¯ãã»ãŒæ¬¡ã®ããã«ãã³ãã¬ãŒãããžãã¯ã䜿çšããŠäœæãããŸãã
- ãªããžã§ã¯ãã®åºæ¬ãªã¹ããèšå®ãããŸãïŒäŸãšåãæ¹æ³ã§ïŒ
- åã©ãããŒã¯ãå¯èœãªå ŽåãçŸåšã®ã¿ã€ãã®ãªã¹ãããåã¿ã€ãã«é çªã«é©çšãããŸãã ã©ãããŒèªèº«ãç¹å®ã®ã¿ã€ããšéä¿¡ããæ¹æ³ã決å®ããŸãã ãã€ã³ãã£ã³ã°çµæïŒæ°ããã¿ã€ãïŒãçŸåšã®ã¿ã€ããªã¹ãã«è¿œå ãããŸãã
ãã®ã¢ã¯ã·ã§ã³ã¯ãã³ã³ãã€ã«æ®µéã§ãã³ãã¬ãŒãã䜿çšããŠå®è¡ãããçŽ200è¡ã®ã³ãŒããå¿
èŠã§ãã æ°ããã©ãããŒïŒããã³ã©ãããŒããããããã¹ãŠã®æ°ããã¿ã€ãïŒãè¿œå ããã«ã¯ãçŽ10è¡ã ããèšè¿°ããå¿
èŠããããŸãããæ°ããã¿ã€ãã¯æ¢åã®ã³ãŒãã«ãã£ãŠèªåçã«ååŸãããŸãã
7ã
äžèšã®é¢æ°ã«å ããŠãå®éã«ã¯ãããã«ããã€ãã®ããªã¢ã³ããå®è£
ãããŠããŸãïŒããšãã°ãMakeDescriptorNonStrictã¯ãç§åŠã«æªç¥ã®åã«é©çšãããå Žåã«-1ïŒéåžžã®ã³ã³ãã€ã«ãšã©ãŒã§ã¯ãªãïŒãè¿ããŸãïŒã CallWithTypeã«ã¯ãããšãã°2ã€ã®ãã€ã³ã¿ãŒã䜿çšããŠãã¡ã³ã¯ã¿ãŒãåŒã³åºãä»ã®ãªãã·ã§ã³ããããŸãïŒ1ã€ã¯ç¶æ¿ããªãŒã«ç¹åããããã«äœ¿çšãããã1ã€ã¯å®éã®åã決å®ããããã«äœ¿çšã§ããŸãïŒã
CallWithIntãªãªãŒã¹
æåŸã®ïŒæãé£ããïŒã¹ããããå®è¡ããããšã¯æ®ããŸããåmpl :: int_ <N>ïŒïŒã®ãã¡ã³ã¯ã¿ãŒãåŒã³åºãé¢æ°ãäœæããŸããããã§ãNã¯ã©ã³ã¿ã€ã å€æ°å
ã«æ ŒçŽãããå€ã«å¯Ÿå¿ããŸãã ããã¯ããããæãé£ããéšåã§ãããªããªãã ã©ã³ã¿ã€ã å€ãåã«å€æããã®ã¯åœŒå¥³ã§ãã
ã¢ã€ãã¢ã¯éåžžã«ç°¡åã§ãã
ã¹ã€ãããããšãã°100åã®èŠçŽ ãæã€é¢æ°ãäœæããŸãããã®é¢æ°ã¯å€mpl :: int <N>ãæã€ãã¡ã³ã¯ã¿ãŒãåŒã³åºãå¿
èŠããããŸããããã§ãNã¯é¢æ°ã«æž¡ãããå€æ°ã®å€ã«å¯Ÿå¿ããŸãã å¥ã®ééãå€æããããã«æ±ããããå ŽåãåçŽã«è¿œå ã®äžæ£è¡çºãè¡ããŸãããªãã»ãããšãã³ãžã®åå²ã§ãã ãããã£ãŠãããšãã°ã56 ... 156ã®ééã§æ°å€ãåã«å€æããããã«æ±ããããå Žåã56ã«æž¡ãããå€æ°ããæ¯åæžç®ããã ãã§ãããåã«å€æããåŸã56ãè¿œå ããŸãïŒãã ããåã«ïŒïŒã éé200..400ããæ°å€ãå€æããããã«æ±ããããå Žåãæåã«ãããã»ã¯ã·ã§ã³ã100ãã«åå²ãã次ã«ã»ã¯ã·ã§ã³ã®æ°ãšã»ã¯ã·ã§ã³å
ã®ãªãã»ãããèšç®ããå¿
èŠããããŸãã
ç§ã¯ãããäžå¯è§£ã«èª¬æããŠãããšæãã®ã§ã
ããã«ããããã®ãã©ãŒã³ãŒãããããŸã ã
åèïŒ
0ã
å€ãã®ãã:(
1ã
å®éã«ã¯ãã¹ã€ããã«ã¯100ã®ã±ãŒã¹ããããŸãïŒå€ã¯å®éšçã«éžæãããã³ãŒãã¯2以äžã®ä»»æã®å€ã«å¯ŸããŠåäœå¯èœã§ãïŒã
2ã
çŸå®ã®äžçã§ã¯ãã¹ã€ããã±ãŒã¹ã¯ãã¯ãã«ãã£ãŠçæãããŸãã
3ã
éãåäœããŸãã ãšãŠãéãã ãã®ãããªæ®å¿ãªè¡šçŸã§ãããæ¯æãå¿
èŠããããŸãã ã³ã³ãã€ã©ã¯ãæ«å°Ÿååž°ãåãæ¿ããŠåçŽãªå®è£
ãæé©åã§ããŸããã§ãã:(
ç³èŸŒã¿
ããã§æ¬¡ã®ããšãã§ããŸãã
1.ãªããžã§ã¯ããäœæããã«ã¯ããªããžã§ã¯ãã®ã¿ã€ããæ¢ç¥ã®ã¿ã€ãã®ãªã¹ãã«è¿œå ããŸãã 以åã¯ãæ°ããã¿ã€ãã®ãªããžã§ã¯ããè¿œå ããå Žåããã¹ãŠã®ã¹ã€ããã±ãŒã¹ãã¿ã€ãããšã«æ€çŽ¢ããå¿
èŠããããŸããããã¹ã€ããã±ãŒã¹ã¯ãŸã£ãããããŸãããã€ãŸãããã¹ãŠã®æ°ããã¿ã€ãã®ãªããžã§ã¯ãããããã«ããµããŒããããŸãã ãã®äŸã¯ãã¹ã€ããã±ãŒã¹ã®æ¶å€±ã瀺ããŠããŸãã
ããã¯ïŒ
int nObjectType = ResolveObjectType ïŒ ... ïŒ ;
ã¹ã€ãã ïŒ nObjectType ïŒ
{
ã±ãŒã¹ 1 ïŒ
æ°ãã TObject1 ïŒ ïŒã è¿ã ãŸãã
ã±ãŒã¹ 2 ïŒ
æ°ãã TObject2 ïŒ ïŒã è¿ã ãŸãã
ã±ãŒã¹ 3 ïŒ
æ°ãã TObject3 ïŒ ïŒã è¿ã ãŸãã
ã±ãŒã¹ 4 ïŒ
æ°ãã TObject4 ïŒ ïŒã è¿ã ãŸãã
/ * ... 100件以äžã®ã±ãŒã¹ãããã«å
¥ããŸã* /
ããã©ã«ã ïŒ
NULLã è¿ã ãŸã ã
} ;
次ã®ããã«ãªããŸããïŒ
//ïŒ ãã®ã©ãããŒã«ãããå®éã®ãªããžã§ã¯ãã¿ã€ããå€å¥ã§ããŸãã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TBaseã ã¯ã©ã¹ TObject = TBase >
struct CTypeWrapper
ïŒ ãããªã㯠TBase
{
//ïŒ ãã®ã€ã³ã¹ã¿ã³ã¹ã«å¯Ÿå¿ããåèšè¿°åãè¿ããŸãã
ä»®æ³ æŽæ° TypeDescriptor ïŒ ïŒ const
{
MakeDescriptor < TObject > ïŒ ïŒã è¿ã ãŸãã
}
} ;
//ïŒ ãªããžã§ã¯ããäœæããã®ã«åœ¹ç«ã¡ãŸãã å®éãããã¯ãªããžã§ã¯ãåã§åŒã³åºããããã¡ã³ã¯ã¿ãŒã§ãã
ã¯ã©ã¹ CreateObjectHelper
{
å
¬é ïŒ
//æ»ãå
typedef IObject *
R ;
ãã©ã€ããŒã ïŒ
ãã³ãã¬ãŒã < ã¯ã©ã¹ TBaseã ã¯ã©ã¹ TObject >
ã€ã³ã©ã€ã³ TBase * MakeObject ïŒ ïŒ const
{
æ°ãã CObjectTypeWrapper < TBaseãTObject > ïŒ ïŒã è¿ã ãŸãã
}
å
¬é ïŒ
//ïŒ äžè¬çãªã±ãŒã¹
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
ã€ã³ã©ã€ã³ TObject *æŒç®åïŒ ïŒ ïŒ TObject * ã... ïŒ const
{
MakeObject < TObjectãTObject > ïŒ ïŒã è¿ã ãŸãã
}
ã€ã³ã©ã€ã³ IObject *æŒç®åïŒ ïŒ ïŒ boost :: mpl :: void_ ïŒ const
{
assert ïŒ ïŒ "Type Descriptor Is BrokenïŒMust'n not here hereïŒ ïŒïŒ ;
NULLã è¿ã ãŸã ã
}
å
¬é ïŒ
// IObjectType1ãã掟çãããªããžã§ã¯ãã®ç¹æ®ãªã±ãŒã¹
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
IObject *æŒç®åïŒ ïŒ ïŒ TObject * ãIObjectType1 * ïŒ const
{
// ...
}
// IObjectType2ãã掟çãããªããžã§ã¯ãã®ç¹æ®ãªã±ãŒã¹
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
IObject *æŒç®åïŒ ïŒ ïŒ TObject * ãIObjectType2 * ïŒ const
{
// ...
}
} ;
...
int nObjectType = ResolveObjectType ïŒ ... ïŒ ;
ObjectTraitsãè¿ã:: CallDoublePointerBasedFunctorWithObjectType ïŒ
CreateObjectHelper ïŒ ïŒ ã
nObjectType ïŒ ;
2. dynamic_castã䜿çšããã«ããªããžã§ã¯ãã®å®éã®ã¿ã€ãã«å¿ããŠãç¶æ¿ããªãŒã®äžå€®ã«ããã¯ã©ã¹ã®åäœãå€æŽããŸãïŒCallWithTypeã䜿çšããã¢ãããŒãã¯ãã¯ã©ã¹éå±€ã§çŽ50åé«éã§ãïŒã
ãã³ãã¬ãŒã < ã¯ã©ã¹ TKind >
struct IsKindOfHelper
{
typedef bool
R ;
ã€ã³ã©ã€ã³ ããŒã«æŒç®åïŒ ïŒ ïŒ ... ïŒ const
{
falseã è¿ã ãŸã ã
}
ã€ã³ã©ã€ã³ ããŒã«æŒç®åïŒ ïŒ ïŒ TKind * ïŒ const
{
trueã è¿ã ãŸã ã
}
} ;
ãã³ãã¬ãŒã < ã¯ã©ã¹ TObject >
ã€ã³ã©ã€ã³ bool IsKindOf ïŒ int nTypeDescriptor ïŒ
{
Return CallWithType ïŒ IsKindOfHelper < TObject > ïŒ ïŒ ãnTypeDescriptor ïŒ ;
}
...
// TypeDescriptorã¯ãä»®æ³ãªããžã§ã¯ãã§ãããå®éã®ãªããžã§ã¯ãã¿ã€ãã®èšè¿°åãè¿ããŸãã
//åã®äŸã§ç€ºããå®è£
ïŒãã®é¢æ°ãæåã§èšè¿°ããå¿
èŠã¯ãããŸããïŒ
if ïŒ IsKindOf < ISettable > ïŒ this- > TypeDescriptor ïŒ ïŒ ïŒ ïŒ
{
//äœãããã
}
ä»ã«
{
//å¥ã®ããšããã
}
3.åãšããŠçŽæ¥åèšè¿°åãå«ãå€æ°ãæäœããæ©èœã ããã¯ãã©ã®çš®é¡ã®ãªããžã§ã¯ãã¿ã€ããäœæãããã決å®ããæé ã§éåžžã«åœ¹ç«ã¡ãŸãïŒã¿ã€ããå€ãã®å€éšèŠå ã«äŸåããå ŽåïŒã
int ApplySomeWrapper ïŒ int nType ïŒ
{
bool bShouldBeWrapperApplied = ... ;
if ïŒ bShouldBeWrapperApplied ïŒ
{
// IsWrapperApplicableã¯ãCallWithTypeã䜿çšããŠnTypeãå®éã®åTObjectã«å€æããŸã
// WrapperTraitsãåŒã³åºããŸã:: CSomeWrapper :: IsApplicable <TObject> ::å€ã¡ã¿é¢æ°
if ïŒ IsWrapperApplicable < WrapperTraits :: CSomeWrapper > ïŒ nType ïŒ ïŒ
{
// IsWrapperApplicableã¯ãCallWithTypeã䜿çšããŠnTypeãå®éã®åTObjectã«å€æããŸãã
// WrapperTraitsãåŒã³åºããŸã:: CSomeWrapper :: MakeWrappedType <TObject> ::åã¡ã¿é¢æ°
//ã©ãããããåã解決ããããã«ããã®åã®MakeDescriptorãåŒã³åºããŸãã
MakeWrappedType < WrapperTraits :: CSomeWrapper > ïŒ nType ïŒ ;ãè¿ããŸãã
}
}
nTypeãè¿ããŸãã
}