ãã®èšäºã§ã¯ãæšæºã®C ++ãã¯ãããžãŒã䜿çšããŠããŸããŸãªãªããžã§ã¯ããžã®åŒã³åºãã管çããããã®éåžžã«çç£æ§ã®é«ãïŒã³ã³ãã€ã«æã«çµã¿èŸŒãŸããïŒç°¡åã«ã¹ã±ãŒã©ãã«ãªã³ãŒããååŸã§ããã¡ã«ããºã ã®ããã€ãã瀺ããŸãã
ã¿ã¹ã¯ã«ã€ããŠ
å°ãåã«ããŠãŒã¶ãŒïŒå®è¡æïŒæ
å ±ã«å¿ããŠãããã°ã©ã ã³ã¢å
ã§ããŸããŸãªã¢ã¯ã·ã§ã³ãå®è¡ããå°ããªã¢ãžã¥ãŒã«ãå®è£
ããå¿
èŠããããŸããã åæã«ãäž»ãªèŠä»¶ã¯ãã³ãŒãã®æå€§ããã©ãŒãã³ã¹ïŒæé©åå¯èœæ§ïŒããµãŒãããŒãã£ã®äŸåé¢ä¿ã®æ¬ åŠãããã³æ©èœã远å ããå Žåã®åçŽãªã¹ã±ãŒãªã³ã°ã§ããã
ç°¡åãã€èªã¿ãããããããã«ãã³ãŒãäŸã§ã¯æãè€éãªããŒã¡ã«ããºã ã®ã¿ã瀺ããŸãã O2æé©åã®ããã®Microsoftã³ã³ãã€ã©çšã®ãã·ã³ã³ãŒãã®äŸãæäŸãããŠããŸãã
æåã®ã¹ããã
ãCãã¹ã¿ã€ã«ã®åé¡ã®è§£æ±ºçã¯ãããŒã¿ãåŠçãããšãã«å€ãèšå®ãããŠãã颿°ãžã®ãã€ã³ã¿ãŒãåã«äœ¿çšããããšã§ãã ãã ãããã€ã³ã¿ãŒèªäœã«å ããŠãå颿°ã®è¿œå æ
å ±ãä¿åããå¿
èŠããããŸããã ãã®çµæãæãäžè¬çãªãœãªã¥ãŒã·ã§ã³ãæäŸããããã«ãéžæã¯å¿
èŠãªãã£ãŒã«ããšã¡ãœããã®ã»ãããæã€æœè±¡ã¯ã©ã¹ã«åºã¥ããŠããŸããã
ãªããžã§ã¯ãã¢ãããŒãã«ãããäœã¬ãã«ã®å®è£
ããæœè±¡åããããåºãæŠå¿µãæ±ãããšãã§ããŸããããã«ãããã³ãŒããšããã€ã¹å
šäœã®çè§£ã容æã«ãªããŸãã
ãã®ãããªã¯ã©ã¹ã®ç°¡åãªäŸïŒ
struct MyObj { using FType = int( *)(int, int); virtual int operator() ( int a, int b ) = 0; virtual ~MyObj() = default; };
ããã§ã¯ãä»®æ³æŒç®åã
ïŒïŒ ããäž»ãªãã®ã§ãããä»®æ³ãã¹ãã©ã¯ã¿ã¯
æãããªçç±ã§å¿
èŠã§ãããFTypeã¯åŒæ°ã®åãšæ»ãå€ã«é¢ããŠmainã¡ãœããã®ã»ãã³ãã£ã¯ã¹ãå®çŸ©ããã ãã§ãã
åæ§ã®ã¯ã©ã¹ãããããã颿°ãžã®ãã€ã³ã¿ãŒã䜿çšããæäœã¯ãMyObjåã®ãã€ã³ã¿ãŒãæäœããããšã§çœ®ãæããããŸãã ãã€ã³ã¿ã¯ãªã¹ããŸãã¯ããŒãã«ãªã©ã«äŸ¿å©ã«ä¿åã§ããæ®ãã¯é©åã«åæåããã ãã§ãã äž»ãªéãã¯ããªããžã§ã¯ããç¶æ
ãæã€ããšãã§ããç¶æ¿ã¡ã«ããºã ããããã«é©çšã§ããããšã§ãã ããã«ãããå€éšã©ã€ãã©ãªãããã®ã³ãŒãã«ããŸããŸãªæ¢è£œã®æ©èœã远å ããæ©èœã倧å¹
ã«æ¡åŒµããã³ç°¡çŽ åãããŸãã
ãã®ã¢ãããŒãã«ã¯ããã1ã€ã®éèŠãªå©ç¹ããããŸããçŽæ¥åŒã³åºãå¶åŸ¡ãä»®æ³åã¡ã«ããºã ã«è»¢éãããã³ã³ãã€ã©ã¬ãã«ã§ãšã©ãŒãæé©åã®åé¡ããä¿è·ãããŸãã
åã蟌ã¿
å®éãããã°ã©ã ãæé©ã«åäœãããããã®æãéèŠãªã¹ãããã¯ãã€ã³ã©ã€ã³ã³ãŒããæžãããšã§ãã åºæ¬çã«ãããã«ã¯ãå®è¡ãããåœä»€ã®ã·ãŒã±ã³ã¹ãããŒã¿ã®ã©ã³ã¿ã€ã ã«æå°éã«äŸåããããšãå¿
èŠã§ãã ãã®å Žåãã³ã³ãã€ã©ã¯ãã¢ãã¬ã¹ã«ç§»åïŒåŒã³åºãïŒããããäžèŠãªã³ãŒããæšãŠãããã代ããã«ãåŒã³åºãã®å Žæã«é¢æ°ã®ã³ãŒããåã蟌ãããšãã§ããŸãã åãåºæºã䜿çšãããšãé·ããžã£ã³ããé »ç¹ãªããã»ããµãã£ãã·ã¥ã®å€æŽãåé¿ããŠãã·ã³ã³ãŒããåéã§ããŸãããããã¯ãŸã£ããå¥ã®è©±ã§ãã
æ®å¿µãªããããã®å ŽåããŠãŒã¶ãŒããŒã¿ã®ã¢ã¯ã·ã§ã³ã®éžæã«ã¯æãããªåé¡ããããŸãã ãã®ããã»ã¹ã¯ä»®æ³åã®ã¡ã«ããºã ã«ç§»è¡ãããŠãããæ¬¡ã«è¡ãããšã¯ãä»ã®ãã¹ãŠãçµã¿èŸŒãŸããŠããããšã確èªããããšã§ãã ãããè¡ãã«ã¯ããµãŒãããŒãã£ã®æ©èœã®ç¶æ¿ãšåŒã³åºããé©çšããŠããªãŒããŒããŒããããã¡ãœããå
ã§è»¢éããå¿
èŠããããŸãã ãã®å Žåãããããæ£åžžã«çµ±åããã³æé©åã§ããŸãã
ç¶æ¿
æåã®ã¹ãããã¯ãæœè±¡ã¯ã©ã¹ã®ç¶æ¿ãçŽæ¥åŠçããããšã§ãã æãç°¡åãªæ¹æ³ã¯ãç¶æ¿äžã«ãªãã¬ãŒã¿ãŒãæåã§ãªãŒããŒããŒãããããšã§ãã äŸïŒ
struct : public MyObj { int operator()( int a, int b ) override { return a + b; }; }addObj;
ãã®å Žåãä»®æ³ã¡ãœããã®æé©åãããåŒã³åºãã¯ãããã«2ã€ã®æ°å€ã®å ç®ã«ç§»è¡ããããšãããããŸãã O2ãæé©åãããšãMSVSã¯*ïŒã¬ãžã¹ã¿ã®æºåãåŒæ°ã®ã¹ã¿ãã¯ïŒãåŒã³åºãããã®ãããæ¬¡ã®ãã·ã³ã³ãŒããçæããŸãã
push dword ptr [b] mov eax,dword ptr [esi] mov ecx,esi push dword ptr [a] call dword ptr [eax]
ãããŠå®éã«ãªãŒããŒããŒããããã¡ãœããã®ããã®ãã®ãããªã³ãŒãïŒ
push ebp mov ebp,esp mov eax,dword ptr [a] add eax,dword ptr [b] pop ebp ret 8
*æåã®éšåã¯ãåŒã³åºãèªäœã®ã»ãã³ãã£ã¯ã¹ã®ã¿ã«äŸåããããããã¹ãŠã®ã±ãŒã¹ã§å®å
šã«åäžã§ãããããã£ãŠããã®ã³ãŒãã¯ããã«æ¬ èœããŸãã ãã®èšäºã§ã¯ãåžžã«res = (*po)(a, b);
ãªãã·ã§ã³ã䜿çšããŸãres = (*po)(a, b);
ãå Žåã«ãã£ãŠã¯ãæé©åãããã«åªããŠããå ŽåããããŸããããšãã°ãg ++ã¯æŽæ°ã®æãããã¿ã2ã€ã®åœä»€ïŒleaãretïŒã«å§çž®ã§ããŸãã ãã®èšäºã§ã¯ãç°¡æœã«ããããã«ãMicrosoftã³ã³ãã€ã©ãŒã§ååŸããäŸã«éå®ããŸãããLinuxã®äžã§g ++ã§ãã³ãŒãããã¹ããããããšã«æ³šæããŸãã
ãã¡ã³ã¯ã¿ãŒ
è«ççãªç¶ç¶ãšã¯ãããµãŒãããŒãã£ã®æ©èœã§å®è£
ãããè€éãªã³ãŒããå®è¡ããå¿
èŠãããå Žåã¯ã©ããªããããšãã質åã§ãã åœç¶ããã®ã³ãŒãã¯MyObjåŸç¶è
ã®ãªãŒããŒããŒãã¡ãœããå
ã§å®è¡ããå¿
èŠããããŸãããã±ãŒã¹ããšã«ç¬èªã®ïŒå¿åã§ãã£ãŠãïŒã¯ã©ã¹ãæåã§äœæãããªããžã§ã¯ããåæåããŠã¢ãã¬ã¹ãæž¡ãå Žåãçè§£ãããããšã¹ã±ãŒã©ããªãã£ã«ã€ããŠãèŠããŠããå¿
èŠã¯ãããŸããã
幞ããªããšã«ãC ++ã«ã¯ãã®ããã®åªãããã³ãã¬ãŒããšã³ãžã³ããããŸããããã¯ãã³ãŒãã®ã³ã³ãã€ã«æã®è§£æ±ºããããã£ãŠåã蟌ã¿ãæå³ããŸãã ãããã£ãŠããã¡ã³ã¯ã¿ãŒããã©ã¡ãŒã¿ãŒãšããŠåãåãåçŽãªãã³ãã¬ãŒããäœæããå¿åã®MyObjç¶æ¿ã¯ã©ã¹ãäœæããŠããªãŒããŒããŒããããã¡ãœããå
ã§çµæã®ãã©ã¡ãŒã¿ãŒãåŒã³åºãããšãã§ããŸãã
ãããïŒãã¡ãããããããïŒãã©ã ããä»ã®åçãªããžã§ã¯ãã¯ã©ãã§ããããïŒ C ++ã®
ã©ã ãã¯ããã®å®è£
ãšåäœãèæ
®ããŠã颿°ãšããŠã§ã¯ãªããªããžã§ã¯ããšããŠæ£ç¢ºã«èªèãããå¿
èŠãããããšã«æ³šæããŠ
ãã ãã ã æ®å¿µãªãããC ++ã®ã©ã ãåŒã¯ãã³ãã¬ãŒããã©ã¡ãŒã¿ãŒã®èŠä»¶ãæºãããŠããŸããã 圌ãã¯17çªç®ã®æšæºã§ãã®åé¡ãä¿®æ£ããããšèããŠãããããããªããŠããã¹ãŠãããã»ã©æªãããã§ã¯ãããŸããã
ããã§ã·ã³ãã«ã§ãšãŠã楜ãã解決çãæ¢ã
ããŸãã ã æ¬è³ªçã«ã¯ãã¿ã³ããªã³ãšããã«èžããªããã颿°ãžã®åŒæ°ãšããŠåçãªããžã§ã¯ããæ£çŽã«è»¢éããããšã«ãããŸãããã³ã³ãã€ã©ã¯ãã®ã³ãŒããéåžžã«ããŸãæé©åããå¿
èŠãªãã®ããã¹ãŠåã蟌ãããšãã§ããŸãã
çµæãšããŠãå¿
èŠãªçµæãäžããã©ãããŒã¯ã©ã¹ãšã©ãããŒé¢æ°ãšããå°ããªãã¢ãäœæã§ããŸãã
template<class Func> class Wrapping : public MyObj { Func _f; public: Wrapping( Func f ) : _f( f ) {}; int operator()( int a, int b ) override { return _f( a, b ); } }; template<class Func> Wrapping<Func>* Wrap( Func f ) { static Wrapping<Func> W( f ); return &W; }
ãã€ã³ã¿ãŒãåæåããã«ã¯ãWrap颿°ãåŒã³åºããŠãç®çã®ãªããžã§ã¯ããåŒæ°ãšããŠæž¡ãã ãã§ãã ããã«ããã¡ã³ã¯ã¿ãŒã®æŠå¿µã®ç¹æ§ã«ããïŒããã³ããã¯ãŸãã«ããã§ã®äœæ¥ã§ãïŒãåŒæ°ã¯ãå®è¡å¯èœãªãªããžã§ã¯ãã§ãããããŸãã¯ç°ãªãã¿ã€ãã§ãã£ãŠãã察å¿ããåŒæ°ã®æ°ãæã€é¢æ°ã«ãªããŸãã
åŒã³åºãã®äŸã¯æ¬¡ã®ãšããã§ãã
po = Wrap( []( int a, int b ) {return a + b; } );
è€éãªãã¥ãŒã«ããããããããªãŒããŒããŒããããæŒç®åã
ïŒïŒ ãã®äžé£ã®åœä»€ã¯éåžžã«åçŽã§ãå®éã«ã¯æåã®ç¶æ¿ãšåã蟌ã¿ã«ãã£ãŠåŸããããã®ãšåäžã§ãã
push ebp mov ebp,esp mov eax,dword ptr [a] add eax,dword ptr [b] pop ebp ret 8
ã©ãããåŒã³åºããããšããã¹ãŠã®è€éãªæ¡ä»¶ä»ãé·ç§»ãšåæåãçºçããŸãããã®åŸãä»®æ³ã¡ãœãããåŒã³åºãããã®ã¡ã«ããºã ã®ã¿ãæ®ããŸãã ããã«ãéçãªããžã§ã¯ãã䜿çšããäœæ¥ãè¡ãããŠããŸããã€ãŸããããŒããšãã³ã°ãžã£ã³ãã®åŒã³åºãããªãããšãæåŸ
ãããŸãã
ã»ãŒãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãåã蟌ãããšãã§ããã®ã¯è峿·±ãã§ãã äŸã®ã³ãŒãïŒ
struct AddStruct { int operator()( int a, int b ) { return a + b; } }; ... op = Wrap( AddStruct() );
ãªãŒããŒããŒããªãã¬ãŒã¿ãŒçšã®æ¬¡ã®ãã·ã³ã³ãŒãããããŸãã
push ebp mov ebp,esp mov eax,dword ptr [a] add eax,dword ptr [b] pop ebp ret 8
ã€ãŸã æåã€ã³ã¹ããŒã«ãšåãã§ãã newãä»ããŠäœæããããªããžã§ã¯ãã§ããåæ§ã®ãã·ã³ã³ãŒããååŸã§ããŸããã ãã ãããã®äŸãæ®ããŠãããŸãã
æ©èœ
äžèšã®ã³ãŒãã«ã¯ãéåžžã®æ©èœã«é¢ããŠé倧ãªåé¡ããããŸãã ãã®ã©ãããŒã¯ãåã®é¢æ°ãžã®ãã€ã³ã¿ãŒãåŒæ°ãšããŠç°¡åã«åãå
¥ããããšãã§ããŸãã
int sub( int a, int b ) { return a + b; }; ... po = Wrap( sub );
ãã ãããªãŒããŒããŒããããã¡ãœããã®ãã·ã³ã³ãŒãã«ã¯ãããããé·ç§»ã䌎ãå¥ã®åŒã³åºãããããŸãã
push ebp mov ebp,esp push dword ptr [b] mov eax,dword ptr [ecx+4] push dword ptr [a] call eax add esp,8 pop ebp ret 8
ã€ãŸããç¹å®ã®ç¶æ³ïŒã€ãŸãã颿°ãšãªããžã§ã¯ãã®æ§è³ªãç°ãªãïŒã«ããã颿°ããã®æ¹æ³ã§æ§ç¯ããããšã¯ã§ããŸããã
ã»ãã³ãã£ã¯ã¹ãåã颿°
èšäºã®æåã«æ»ããšãåã蟌ã¿ã®ããã«ããã³ãã¬ãŒããã©ã¡ãŒã¿ãŒãä»ããŠç®çã®ãªããžã§ã¯ãïŒãã®å Žåã¯é¢æ°ïŒãæž¡ãããšãã§ããããšãæãåºããŠãã ããã ãããŠä»ã颿°ãã€ã³ã¿ã«å¯ŸããŠã®ã¿ããã®ã¢ã¯ã·ã§ã³ãèš±å¯ãããŠããŸãã åŒã³åºãããã¡ãœããã®ã»ãã³ãã£ã¯ã¹ãå®çŸ©ããæœè±¡ã¯ã©ã¹ã§å®çŸ©ãããåã䜿çšãããšããã®ãããªé¢æ°å°çšã®ãã©ãããŒãšã©ãããŒãã®ãã¢ãç°¡åã«ãªãŒããŒããŒãã§ããŸãã
template<class Func, Func f> struct FWrapping : public MyObj { int operator ()( int a, int b ) override { return f( a, b ); } }; template<MyObj::FType f> FWrapping<MyObj::FType, f>* Wrap() { static FWrapping<MyObj::FType, f> W; return &W; }
次ã®åœ¢åŒã®é¢æ°ã®ãªãŒããŒããŒããããã©ããã®ã©ããïŒ
int add( int a, int b ) { return a + b; } ... po = Wrap<add>();
æåç¶æ¿ã§ååŸãããã®ãšåäžã®æé©ãªãã·ã³ã³ãŒããååŸã§ããŸãã
push ebp mov ebp,esp mov eax,dword ptr [a] add eax,dword ptr [b] pop ebp ret 8
åªããã»ãã³ãã£ã¯ã¹ãæã€é¢æ°
æåŸã®è³ªåã¯ãåã蟌ã¿ã«å¿
èŠãªé¢æ°ãMyObjã§å®£èšãããåãšäžèŽããªãå Žåã«æ®ããŸãã ãã®å Žåãã©ãããŒé¢æ°ã®å¥ã®ãªãŒããŒããŒããç°¡åã«è¿œå ã§ããŸãããã®ãªãŒããŒããŒãã§ã¯ãåã¯å¥ã®ãã³ãã¬ãŒããã©ã¡ãŒã¿ãŒãšããŠæž¡ãããŸãã
template<class Func, Func f> FWrapping<Func, f>* Wrap() { static FWrapping<Func, f> W; return &W; }
ãã®é¢æ°ãåŒã³åºãã«ã¯ã転éããã颿°ã®ã¿ã€ããæåã§ç€ºãå¿
èŠããããŸãããããã¯å¿
ããã䟿å©ã§ã¯ãããŸããã ã³ãŒããç°¡çŽ åããã«ã¯ã
decltype( )
ããŒã¯ãŒãã䜿çšã§ããŸãã
po = Wrap<decltype( add )*, add>();
decltype
åŸã«ã
* ããä»ããå¿
èŠãããããšã«æ³šæããããšãéèŠ
decltype
ãããããªããšãéçºç°å¢ã§ã¯ããããã®åŒæ°ãæºããWrapå®è£
ã®æ¬ åŠã«é¢ãããšã©ãŒã¡ãã»ãŒãžã
decltype
ãããå ŽåããããŸãã ããã«ãããããããã»ãšãã©ã®å Žåããããžã§ã¯ãã¯æ£åžžã«ã³ã³ãã€ã«ãããŸãã ãã®ççŸã¯ããã³ãã¬ãŒãã«æž¡ããšãã«åãæ±ºå®ããããã®èŠåãšãå®éã«ã¯
decltype
æäœã®åçã«ãã£ãŠ
decltype
ããŸãã ãšã©ãŒã¡ãã»ãŒãžãåé¿ããã«ã¯ã
std::decay
ãªã©ã®æ§é ã䜿çšããŠãæ£ããå眮æãä¿èšŒããŸããããã¯ãåçŽãªãã¯ãã§ã©ããããã®ã«äŸ¿å©ã§ãã
#define declarate( X ) std::decay< decltype( X ) >::type ... po = Wrap<declarate( add ), add>();
ãŸãã¯ããšã³ãã£ãã£ãäœæããããªãå Žåã¯ãã³ã³ãã©ã€ã¢ã³ã¹ãæåã§è¿œè·¡ããŸãã
ãã¡ãããå°ãªããšãå倿ãå¿
èŠãªã®ã§ããã®ãããªé¢æ°ãåã蟌ããšãã®ãã·ã³ã³ãŒãã¯ç°ãªããŸãã ããšãã°ã次ã®ããã«å®çŸ©ããã颿°ãåŒã³åºãå ŽåïŒ
float fadd( float a, float b ) { return a + b; } ... op = Wrap<declarate(fadd), fadd>();
ããã¯éã¢ã»ã³ãã©ãŒããåºãŠããŸãïŒ
push ebp mov ebp,esp movd xmm1,dword ptr [a] movd xmm0,dword ptr [b] cvtdq2ps xmm1,xmm1 cvtdq2ps xmm0,xmm0 addss xmm1,xmm0 cvttss2si eax,xmm1 pop ebp ret 8
äžç·ã«æ©èœãã
Wrap颿°ã®è¿œå ã®ãªãŒããŒããŒããåãåã£ãŠä»ã®é¢æ°ãåã蟌ãã åŸãZenã«ã¢ãããŒãããŠZenãåŒã³åºãããã«å¥ã®ãªãã·ã§ã³ãåŒã³åºãããšã«ããããªãã·ã§ã³ã®1ã€ããªãŒããŒã©ã€ãã§ããŸãã
template<class Func, Func f> FWrapping<Func, f>* Wrap() { static FWrapping<Func, f> W; return &W; } template<MyObj::FType f> FWrapping<MyObj::FType, f>* Wrap() { return Wrap<MyObj::FType, f>(); }
Wrap颿°ã®3ã€ã®ãªãŒããŒããŒãã¯ãã¹ãŠåæã«ååšã§ããããšã«æ³šæããŠãã ããããã³ãã¬ãŒããã©ã¡ãŒã¿ã¯ã颿°ã®åŒæ°ãšããŠããªã¢ãŒãã£ãºã ã«é¢ããåãèŠåã«åŸãããã§ãã
ãã¹ãŠäžç·ã«
äžèšã®çµæãšããŠã50è¡æªæºã®å Žåãååã«
è¿ã*ã»ãã³ãã£ã¯ã¹ãæã€å®è¡å¯èœãªããžã§ã¯ããšé¢æ°ããå¿
èŠãªããããã£ã®è¿œå ãšå®è¡å¯èœã³ãŒãã®æå€§åã蟌ã¿ãåããçµ±ååã«èªåçã«å€æã§ããã¡ã«ããºã ãååŸããŸããã
*ãã®äŸã«ååè¿ããšããããšã¯ãåŒæ°ã®æ°ãäžèŽããäžèŽãŸãã¯æé»çãªå倿ã®å¯èœæ§ãããããšãæå³ããŸãã struct MyObj { using FType = int( *)(int, int); virtual int operator() ( int a, int b ) = 0; virtual ~MyObj() = default; }; template<class Func> class Wrapping : public MyObj { Func _f; public: Wrapping( Func f ) : _f( f ) {}; int operator()( int a, int b ) override { return _f( a, b ); } }; template<class Func, Func f> struct FWrapping : public MyObj { int operator ()( int a, int b ) override { return f( a, b ); } }; template<class Func> Wrapping<Func>* Wrap( Func f ) { static Wrapping<Func> W( f ); return &W; } template<class Func, Func f> FWrapping<Func, f>* Wrap() { static FWrapping<Func, f> W; return &W; } template<MyObj::FType f> FWrapping<MyObj::FType, f>* Wrap() { return Wrap<MyObj::FType, f>(); } #define declarate( X ) std::decay< decltype( X ) >::type
ãã®ã¡ã«ããºã ã®æœåšçãªåé¡ã¯ãç°ãªãæ°ã®åŒæ°ãŸãã¯æ¢çŽïŒæé»ïŒåã§é¢æ°ããã©ãããããå¿
èŠãããããšã§ãã ç¹å®ã®è§£æ±ºçã¯ãã©ãããããã©ã ãå
ã§ãã®ãããªé¢æ°ïŒãã¡ã³ã¯ã¿ãŒïŒãåŒã³åºãããšã§ãã äŸïŒ
int volume( const double& a, const double& b, const double& c ) { return a*b*c; }; ... po = Wrap( []( int a, int b )->int { return volume( a, b, 10 ); } );
ã³ãŒãäŸã¯
ãã¡ãã§ãã ãã«ãããã«ã¯ãC ++ 11ã䜿çšããå¿
èŠããããŸãã åã蟌ã¿ã®éããæããã«ããããã«-O2æé©åã ã³ãŒãã¯ãäžå¿
èŠãªåã蟌ã¿ãé¿ããããã«æºåãããŠããŸãã
______________________________
远å
ã³ã¡ã³ãã«ã¯ãç§ãçããããšããããã€ãã®éèŠãªè³ªåããããŸããã
1ïŒ std::function
éãïŒ
ãŸã第äžã«ãã¿ã¹ã¯ã®æ¬è³ªã¯ã³ãŒã«å¶åŸ¡ãä»®æ³åã¡ã«ããºã ã«è»¢éããããšã§ããïŒãã®ãããªçç±ã¯èšäºã®ç¯å²å€ã§ãïŒã ãããã£ãŠã
Wrap
颿°ã®ãã¹ãŠã®ããªã¢ã³ãã¯
ãç¶æ¿ãããã¯ã©ã¹ãçæããæ¹æ³ãšããŠæ£ç¢ºã«è§£éããå¿
èŠããããŸãã ãããã£ãŠãååŒã³åºãã¯ãæåãã§å®äºããå¿
èŠããããŸã-ã«ãŒãå
ã§é¢æ°ã䜿çšãããšãããã°ã©ã ãæ£ããåäœããªããªããŸãã ããã¯ãåã
std::function
ãšæ¯èŒããŠæ¬ ç¹ã§ãã
2çªç®ã®éèŠãªç¹-ãã®å®è£
ã¯ãåçã¡ã¢ãªã§ã¯æ©èœããŸããã ããã«ãããããã©ãŒãã³ã¹ã®é¢ã§æœåšçãªå©ç¹ãåŸãããŸãã ããã«ãå®éã«åçã¡ã¢ãªãåŒãç¶ã䜿çšããå¿
èŠãããå Žåã
new
æŒç®åã远å ããŠãå颿°å
ã®æ°è¡ã倿Žããã ãã§æžã¿ãŸãã ãã ãããã®å Žåãã¡ã¢ãªã®ã¯ãªãŒãã³ã°ãå¶åŸ¡ããå¿
èŠããããŸãïŒããã¯èªåçã«è¡ãããŸãïŒã
ãã®ã¢ãããŒãã§ã¯ãå®è¡å¯èœã³ãŒããåã蟌ãããšãå¯èœã§ãïŒ
std::function
ã§èµ·ããããšãšåæ§ã«ãåæã«ãä»®æ³åŒã³åºãã¡ã«ããºã ã¯æ©èœãç¶ããŸãã
2ïŒç¶æ
ãç°ãªãåãã¿ã€ãã®ãªããžã§ã¯ãã®ç¹°ãè¿ãåŒã³åºãäžã«Wrap
æ£ããWrap
ãªã
æ°é
ãã®ãã人ã
ã®ãããã§ãåãã¿ã€ãã®ãã¡ã³ã¯ã¿ãŒãåŠçãããšãã«ç°ãªãç¶æ
ã®ç°ãªãã€ã³ã¹ã¿ã³ã¹ã転éããããšãæ£ãããªãïŒæããã§ã¯ãªãïŒã³ãŒããåäœããå¯èœæ§ãæ¬åœã«éããŸããã ãã®å Žåã
Wrapping
ã¯ã©ã¹ã®éçãªããžã§ã¯ãã¯ãæåã®åŒæ°ã§1åã ãåæåãããŸãã ä»ã®ãã¹ãŠã®åŒã³åºãã¯å¹æããããŸããã
æåã«è¡ãããšã¯ããã®ãããªç¶æ³ã«å¯Ÿããä¿è·ã远å ããããšã§ãã ãããè¡ãã«ã¯ã次ã®ããã«ããã©ã°ãç°¡åã«è¿œå ããååæåã詊ã¿ããšãã«äŸå€ãã¹ããŒã§ããŸãã
template<class Func> Wrapping<Func>* Wrap( Func f ) { static int recallFlag{}; if( recallFlag ) throw "Second Wrap of the same type!\n"; recallFlag++; static Wrapping<Func> W( f ); return &W; }
ïŒã¹ããŒã®éæšæºãªããžã§ã¯ãããIã³ããŸãïŒ
ãã ããããã¯åé¡ã®è§£æ±ºçã§ã¯ãªããäºæ
ã®å Žåã®èŠåã«ãããŸããã
ã·ã³ãã«ã§å¹æçãªè§£æ±ºçã¯ãWrap颿°ã®ãã³ãã¬ãŒãã«ãã©ã¡ãŒã¿ãŒïŒããã©ã«ãå€ïŒã远å ããããšã§ãã å¿
èŠã«å¿ããŠããã®ãã©ã¡ãŒã¿ãŒã倿Žãããšãå¥ã®éçã©ããã³ã°ã€ã³ã¹ã¿ã³ã¹ã䜿çšããŠã颿°ã®å¥ã®å®è£
ãããããåŒã³åºãããŸãã
template<int i = 0, class Func> Wrapping<Func>* Wrap( Func f ) {...}
ãã®åŸãåãåã®åŒæ°ãåŒã³åºããã³ã«ããã©ã¡ãŒã¿ãŒã«æ°ããå€ãæž¡ãå¿
èŠããããŸãã ãããæåã§è¡ãã®ã¯ããäžäŸ¿ã§ãã ããã€ãã®è§£æ±ºçããããŸãã
-å®çŸ©æžã¿ãã¯ã__COUNTER__ãŸãã¯__LINE__ã䜿çšããŠå°ããªãã¯ãã远å ããŸãã
-äžèšã®ãã¯ãã«åºã¥ããŠç¹å®ã®ãã³ãã¬ãŒãã«ãŠã³ã¿ãŒãåéããŸãã
-
é£è§£ãªãšããŸããã¯ãªéãé²ã¿ãçŽç²ãªãã³ãã¬ãŒãã«ãŠã³ã¿ãŒãåéããŸãã
æåã®ãœãªã¥ãŒã·ã§ã³ã¯ãéåžžã«ä¿¡é Œæ§ãé«ãã·ã³ãã«ã§ãã ãã ããç°ãªããã¡ã€ã«ã§ã©ããã䜿çšããå Žåã__ LINE__ãã¯ãã¯åãçµæãããããå¯èœæ§ãããã__ COUNTER__ãã¯ãã¯æšæºã§ã¯ãããŸããããã»ãšãã©ã®ã³ã³ãã€ã©ã«å®è£
ãããŠããããšã«æ³šæããŠãã ããã ããã°ã©ã ã®ä»ã®ã¢ãžã¥ãŒã«ãäœããã®åœ¢ã§ãã®ãã¯ãã䜿çšããããã«å¯Ÿããå¯äžã®æš©å©ãå¿
èŠãšããå Žåã«ããç«¶åãçºçããå¯èœæ§ããããŸãã äžè¬çã«ããœãªã¥ãŒã·ã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
#define OWrap( ... ) \ Wrap<__COUNTER__>( __VA_ARGS__ )
ããã«ã颿°åŒæ°ã®äžã§åçŽãªWrapåŒã³åºãã®ãã¯ããå®çŸ©ã§ããŸãã
#define FWrap( ... ) \ Wrap<declarate( __VA_ARGS__ ), __VA_ARGS__>()
2çªç®ã®ãªãã·ã§ã³ã¯ãããšãã°
ããããã³
ããããã®ãœãªã¥ãŒã·ã§ã³ã䜿çšããŠå®è£
ã§ã
ãŸã ã ãã®åŸãåãæ¹æ³ã§ãã¯ãå
ã®çµæã眮ãæããããšãã§ããŸãã
æåŸã« ããããç§ã®æèŠã§ã¯-æãè峿·±ããªãã·ã§ã³ã¯
ãã®èšäºã«è§Šçºãã
ãŠããŸãã å®éãããã¯ããªã埮åŠãªå®è£
ã§ãããå®å
šã«C ++ 11æšæºã®ãã¬ãŒã ã¯ãŒã¯å
ã«ãããŸãã ãã®çµæã次ã®ãããªè¿œå ã®ãã¯ãã䜿çšããã«ãã«ãŠã³ã¿ãŒããã³ãã¬ãŒãã«çŽæ¥çœ®ãæããããšãã§ããŸãã
template<int i = next(), class Func> Wrapping<Func>* Wrap( Func f ) {...}
ããã§ã
next()
ã¯ãã³ãã¬ãŒãã«ãŠã³ã¿ãŒã®å®è£
ã§ãã
ãã®ãããªã³ãŒããå®çšŒåç°å¢ã«æå
¥ããåã«ã3åèããŠãã¹ãŠã®å©çšå¯èœãªåŸæ¥å¡ã«å°ããå¿
èŠãããããšã¯æ³šç®ã«å€ããŸãããçµæã¯éåžžã«è峿·±ãæçšã§ãã ãã®ã¡ã«ããºã ã®è©³çްãªèª¬æãšå®è£
ã«ã€ããŠã¯ã次ã®è¿œå èšäºãŸãã¯å¥ã®èšäºã§èª¬æããŸãã