ããã¯ãC ++ 98/03ã®is_functionã¡ã¿é¢æ°ãã©ã®ããã«èšè¿°ãããã«ã€ããŠã®å°ããªã¬ããŒãã§ãããã®ãããç°ãªãæ°ã®åŒæ°ã«å¯ŸããŠå€ãã®ç¹æ®åãäœæããå¿
èŠã¯ãããŸããã
2016幎ã«ãã®ãããªããšãããã®ã¯ãªãã§ããïŒ çããŸãã ããã¯ææŠã§ãã ãšããããããã¯ããå¯èœãã©ããããšããã«ããŽãªãŒããã®çŽç²ã«çè«çãªæåã®ç 究ã§ãããçŸä»£ã®ã³ã³ãã€ã©ãŒã®åé¡ãæããã«ããŸããã ãã®æ°åããã²ã芧ãã ããã
ã¹ããŒãžã³ã°çè«ã®ãããå®è£
çªå·0å®æœçªå·1å®è£
çªå·2çµè«ã®ä»£ããã«ã¹ããŒãžã³ã°
is_function<T>
ã¯ãã¿ã€ã
T
ããé¢æ°ãã®ã¿ã€ãã§
true
å Žåã¯
true
è¿ãã
true
ãªãå Žåã¯
true
è¿ã
true
ã ãã®ããã調æ»äžã®é¢æ°åã®ããŸããŸãªæ°ã®åŒæ°åã«å¯ŸããŠå€æ°ã®ç¹æ®åã䜿çšããã«ã¡ã¿é¢æ°ãèšè¿°ããå¿
èŠããããŸãã
boostã«ç¹åããå®è£
äŸãèŠãããšãã§ããŸãã çŸæç¹ã§ã¯ãæ倧25åã®åŒæ°ãããããã®ãã¹ãŠã«å€ãã®ã¹ããŒã¹ãå¿
èŠã§ãã
ãªãå°éåããã®ã§ããïŒ C ++ 11ã§ã¯ããã°ãããããŒã«ãç»å ŽããŸãã-
å¯å€é·ãã³ãã¬ãŒã ã ããã¯çããŠããããã«çŸããããšèšããããããããŸãããããã³ãã ãã®ããŒã«ã䜿çšãããšããã³ãã¬ãŒãåŒæ°ã®ãããã®ã·ãŒã±ã³ã¹ãåŠçã§ããŸã
some_template<A1, A2, A3 >
ãã©ã¡ãŒã¿ã®åäžã®ãããã±ãŒãžãããã©ã¡ãŒã¿ããã¯ãšããŠã ãã©ã¡ãŒã¿ããã¯ã¯ãåŒæ°ã®æ°ãäžæãªå Žåã«ãäžè¬åãããç¹æ®åããªãŒããŒããŒããããã³çœ®æãè¡ãã®ã«åœ¹ç«ã¡ãŸãã is_functionãC ++ 11ã§å®è£
ãããã®ã¯ãã®ããŒã«ã§ãã C ++ 98/03ã§ã¯ããã®ãããªããŒã«ã¯ãããŸããã§ããã ã€ãŸããäžè¬çãªã±ãŒã¹ã§ã¯ãç¶æ³ã«å¿ããŠç°ãªãæ°ã®åŒæ°ãæäŸããå¿
èŠãããå Žåãããã¹ãŠã®å Žåãã«ãªãŒããŒããŒããšç¹æ®åãè¡ãå¿
èŠããããŸããã boostã®
variantã
mplãªã©ã®ã©ã€ãã©ãªã®å®è£
ãèŠãå Žåããã®ãããªã³ãŒããè±å¯ã§ããããšã確èªããŠãã ããïŒããªããã»ããµã«ãã£ãŠçæãããããšããããŸãïŒã ã¿ã€ã
T
R(A1, A2)
é¢æ°ã§
T
ãã©ãããå€æããå¿
èŠãããå Žåãæãç°¡åã§æçœãªè§£æ±ºçã¯ã察å¿ããç¹æ®åãäœæããããšã§ããã
template <typename F> struct is_function { }; template <typename R, typename A1, typename A2> struct is_function<R(A1, A2)> { };
å€ãã®å Žåãç°ãªãæ¹æ³ã§ãããè¡ãããšã¯åã«äžå¯èœã§ããã ããŒã¹ãã§ã®å®è£
ã«äžæºããããšã¯æããªãã§ãã ãã-ãããã®ãœãªã¥ãŒã·ã§ã³ã¯æã移æ€æ§ãé«ãããããã£ãŠãç¹ã«ãã®ãããªã©ã€ãã©ãªã®ã³ã³ããã¹ãã§æãæ£ç¢ºã§ãã ããããæè¿ãªä»äºã§ãããªãã§ããããšã¯ç§ã«ãšã£ãŠèå³æ·±ãããšã§ããã
äžè¬çã«ãç§ã¯ãµãŒãã¹ã®ãããã§äžå¹žãªäººã®äžäººã§ãïŒããã¯èŠãç®ã§ããïŒããç§ã¯ãŸã C ++ 03ã§äœæ¥ããŠããŸãã ãããã£ãŠãå€ãã³ãŒããšã®äºææ§ã«é¢ããç§ã®æžå¿µã¯ãé©ãããšã§ã¯ãããŸããã 誰ããèšããããããŸããïŒãã¯ãããã®ãžã£ã³ã¯ã¯ããªãã«äžããããŸããã2016幎ã®åºã§ïŒãã ããã«åæããããšã¯ã§ããŸãããçŽç²ã«äž»èŠ³çãªç«¶äºæèŠã«å ããŠãããããããã€ãã®å©ç¹ãåŒãåºãããšãå€æããŸããã ãããŠãC ++ 03ã®ç²Ÿç¥ã¯ãäžèšã®çç±ã«ããããŸã 颚åããããšãã§ããŸããã§ããã ãããã£ãŠã楜ãã¿ã®ããã ãã«ã
説æã«ç§»ãåã«ãèªè
ã
SFINAEãšã¯äœããã³ã³ãã€ã«æãã§ãã¯ã
èšè¿°ããåºæ¬ååãç解ããå¿
èŠãããããšãèŠåããããšæããŸããæšæºããã®è¡šçŸãæ£ç¢ºã«ç¿»èš³ããŸããã èå³ã®ããèªè
ã¯ãæããªããèªåã§ããã«å¯ŸåŠã§ãããšæããŸãã
çè«ã®ããã
ç¹æ®åã䌎ãå€å
žçãªã¢ãããŒããç§ãã¡ã«åããªãå Žåãããã§ã¯äœã§ããïŒ å°ãéã£ãèãæ¹ãããŠã¿ãŸãããã ä»ã«ã¯ãªãé¢æ°åã®ããããã£ã¯äœã§ããïŒ æšæºïŒC ++ 03ïŒãèŠãŠã¿ãŸãããã
4.3 / 1é¢æ°åTã®å·ŠèŸºå€ã¯ãåãTãžã®ãã€ã³ã¿ãŒãã®å³èŸºå€ã«å€æã§ããŸã ãçµæã¯ãé¢æ°ãžã®ãã€ã³ã¿ãŒã§ãã
ãã®ãããé¢æ°ã¯æé»çã«é¢æ°ãžã®ãã€ã³ã¿ãŒã«å€æã§ããŸãã é
åã«ã¯åãããããã£ããããŸããé
åã¯æé»çã«ãã€ã³ã¿ã«å€æãããŸãã ä»ã«äœããããèŠãŠã¿ãŸãããïŒ
8.3.5 / 3åãã©ã¡ãŒã¿ãŒã®åã決å®ããåŸããTã®é
åããŸãã¯ãTãè¿ãé¢æ° ã åã®ãã©ã¡ãŒã¿ãŒã¯ ããããããTãžã®ãã€ã³ã¿ãŒ ããŸãã¯ãTãè¿ãé¢æ°ãžã®ãã€ã³ã¿ãŒ ãã«èª¿æŽãããŸã ã
ããã¯ããé¢æ°ãã¿ã€ããå¥ã®é¢æ°ã®ãã©ã¡ãŒã¿ãŒãšããŠæå®ãããå Žåãæé»çã«ãã€ã³ã¿ãŒã®ããããã£ãååŸããããšãæå³ããŸãã ããã«åºã¥ããŠããã©ã°ã©ã
13.1ã§ã¯ããã®ãããªå®£èšã¯
void foo(int ());
ããã«å¯Ÿå¿ããŸãïŒã€ãŸãããŸã£ããåãã§ãïŒïŒ
void foo(int (*)());
ããã¯ãã§ã«äœ¿çšã§ããŸãã ããã«åºã¥ããŠãã§ãã¯ãèšè¿°ããç®ã®åã®æ©èœãå€æã§ããŸãã ãã ãããã¹ãŠã¯èŠãç®ã»ã©åçŽã§ã¯ãããŸããããåŸã§ããã«è©³ãã説æããŸãã ãããŸã§ã®éããé¢æ°ãã®ã¿ã€ãã«åºã¥ããŠãä»ã«äœ¿çšã§ãããã®ãèŠãŠã¿ãŸãããã
8.3.4 / 1Dã次ã®åœ¢åŒã§ãã宣èšTD
D1 [å®æ°åŒopt ]
宣èšT D1ã®èå¥åã®åã¯ã掟ç宣èšååãªã¹ãTãã§ãããDã®èå¥åã®åã¯é
ååã§ãã Tã¯é
åèŠçŽ åãšåŒã°ããŸãã ãã®åã¯ãåç
§åãïŒããããcv修食ãããïŒåvoidãé¢æ°åããŸãã¯æœè±¡ã¯ã©ã¹åã§ãã£ãŠã¯ãªããŸããã
ããããããé¢çœãã§ãã ã€ãŸã ãé¢æ°ãåã®èŠçŽ ã®é
åãååŸããããšã¯ã§ããŸããã ããã«å ããŠããªã³ã¯ã®é
åã
void
é
åãããã³æœè±¡ã¯ã©ã¹ã®åã®èŠçŽ ãæã€é
åãååŸããããšã¯ã§ããŸããã æ®ãã®ãªãã·ã§ã³ãé®æãããã§ãã¯ãèšè¿°ãããšãç®ã®åã®æ©èœãæ£ç¢ºã«å€æã§ããŸãã
ãŸãšããŸãã é¢æ°ã«ã¯2ã€ã®ç¹åŸŽããããŸãã ã¿ã€ããæ©èœã
- å¥ã®é¢æ°ã®åŒæ°ã¿ã€ããšããŠäœ¿çšãããå Žåããã€ã³ã¿ãŒã«ãçªç¶å€ç°ãããŸã
- ãã®åã®èŠçŽ ãæã€é
åãäœæããããšã¯ã§ããŸãã
ãããã®ããããã£ãèšç»ã®å®è£
ã«äœ¿çšããŸããå®è£
çªå·0ãäºå
åã®ã»ã¯ã·ã§ã³ã§ç¹å®ãããé¢æ°ãã¿ã€ãã®æåã®æ©èœããå§ããããšæããŸãã çŽ
8.3.5 / 3ã§ãã
次ã®ããã«èŠçŽã§ããŸãããã§ãã¯ãããå
F
ã¯ãçåŒã®å Žåã«é¢æ°ã§ãã
void( F ) == void( F * )
ã
ããã¯ãã¹ãŠéåžžã«ç°¡åã«èãããŸãã ãŸããæåã®å®è£
ãéåžžã«ç°¡åã§ããã ã·ã³ãã«ã ãééã£ãŠããã ãã®ãããå
šäœã説æããããšã¯ããŸãããããã®äžã§äœ¿çšãã1ã€ã®ããããã£ã«ã€ããŠåå¥ã«è©±ããããšæããŸãã ãã®ã³ãŒããæ€èšããŠãã ããã
template <typename F> static void (* declfunc() )( F ); template <typename F> static void (* gen( void (F *) ) )( F ); template <typename F> static void (* gen( void (F ) ) )( F * );
å°æ¥ãèŠæ®ããŠããã®ã³ãŒãã¯èª€ã£ãä»®å®ã«ç±æ¥ãããšèšãã§ãããã ããããClangã³ã³ãã€ã©ãŒïŒããŒãžã§ã³3.4ãŸã§ïŒãGCCã³ã³ãã€ã©ãŒïŒããŒãžã§ã³4.9ãŸã§ïŒãVSã®ã³ã³ãã€ã©ãŒïŒcl 19.xããããã以åïŒã¯ãäºæ³ã©ããã«ã³ã³ãã€ã«ããŸããã ã©ã®ããã«æ©èœããã©ã®ããã«äœ¿çšããäºå®ã ã£ããã説æããŸãã ãŸãããã§ãã¯ã«åœ¹ç«ã€é¢æ°å®£èšãäœæããŸãã
template <typename X> static char (& check_is_function( X ) ) [ is_same<void(*)( F ), X>::value + 1 ];
check_is_functionã«æž¡ãããåã
void(*)( F )
ã«äžèŽããå Žåãé¢æ°ã¯2ã€ã®
char
é
åãžã®åç
§ãè¿ããŸããäžèŽããªãå Žåã¯ã1ã€ã®
char
ãã掟çã
void(*)( F )
sizeof
ã䜿çšããŠæ»ãå€ã®åãåæã§ããŸãïŒã ããã§ã¯ã
F
ãã¿ã€ããé¢æ°ãã«å±ããããšã調æ»äžã®ã¿ã€ãã§ããããšãåãå
¥ããŸãã ããŠããããã·ã³ãã«ãªãã³ãã¬ãŒãã«å
¥ãããšã
template <typename F> struct is_function { template <typename X> static char (& check_is_function( X ) ) [ is_same<void(*)( F ), X>::value + 1 ]; enum { value = sizeof( check_is_function( gen( declfunc<F>() ) ) ) - 1 }; };
äžèšã®ã³ã³ãã€ã©ã§æ¬¡ã®åœ¢åŒã®åŒã確èªã§ããŸãã
is_function<int()>::value; is_function<int>::value; typedef void fcv() const; is_function<fcv>::value;
çµæ1ã0ãããã³1ãããããååŸããŸãïŒå®å
šãªã³ãŒãã¯
ããã«ããã
ããã§å®è¡ã§ã
ãŸã ïŒã ã¯ããããã¯å®å
šã«æ©èœãããœãªã¥ãŒã·ã§ã³ã§ã¯ãããŸãããããã§ã¯ãé¢æ°ãã€ã³ã¿ãšé¢æ°ãåºå¥ããŠããŸããããªã³ã¯ã
void
ãªã©ã«åé¡ããããŸãã ããããããã¯ãã¹ãŠãã€ãã¹ãããŠããã®ã§ãããã«æ³šæãéäžããããããŸããã æå®ããã³ã³ãã€ã©ïŒGCC> = 4.9ãClang> = 3.5ãcl 19.xïŒãããæ°ããã³ã³ãã€ã©ã§åãäŸãå®è¡ããå Žåã¯ãåºåãå€æŽãããŠããããšã確èªããŠãã ããã çµæ1ã0ã0ãããããååŸããŸãã ããã¯ã
cv-qualifier-seq ïŒããã¯æåŸã«åã
const
ãŸãã¯
volatile
ïŒãæã€é¢æ°ã®åïŒå¥ã®é¢æ°ã®åã§ïŒãã€ã³ã¿ãŒããããã£ãååŸäžã«ïŒçœ®æãããïŒãããªã¢ã³ãã®æå¹ãªåŒæ°çœ®æã§ãªããªã£ãããã«çºçããŸãã
template <typename F> static void (* gen( void (F *) ) )( F );
ãªãã§ïŒ ïŒæçµãã©ããïŒãšæ確ã«è¿°ã¹ãããŠããæ°ããæšæºã®å°å
¥ã«ããã
8.3.1 / 4é¢æ°åã«cv修食åãŸãã¯ref修食åãããå Žåãé¢æ°åãžã®ãã€ã³ã¿ãŒã®åœ¢æã¯äžæ£ã§ãã
åæ§ã®ã³ãŒãã«å¯Ÿããã³ã³ãã€ã©ã®ã¢ãããŒããå€æŽãããŸããã ãã®ã¿ã€ãã«ã¢ã¹ã¿ãªã¹ã¯ãè¿œå ããã®ã¯ééã£ã眮æã§ãããããã³ãŒãã¯æ©èœããªããªããŸããã C ++ 03ã§ã¯ãåæ§ã«æ確ãªã«ãŒã«ã¯ãããŸããã§ããïŒå€æŽã«ã€ããŠã¯ã
ãã¡ããåç
§ããŠãã ãã ïŒã ãã¡ãããããã¯ããã§èš±å¯ãããŠãããšããæå³ã§ã¯ãããŸããã ãã ããæšæºã®æèšã®ææ§ãã«ããããã®ç¹ãã¹ãããããæ©äŒãæ®ããŸãããããã¯ä»¥äžã®ãªã³ã¯ã«èšèŒãããŠãããã®ã§ãã
cv-qualifiersãŸãã¯ref-qualifiersãå«ãé¢æ°åãžã®ãã€ã³ã¿ãŒãšåç
§ãèš±å¯ãããŠããªãããããã³ãã¬ãŒãåŒæ°ã®çœ®æäžã«äœæãããå Žåãæšè«ã«å€±æããããšãæ¢åã®æèšããååã«æããã«ããŠããŸãã
ãããã£ãŠãå€ãã®ææ°ã®ã³ã³ãã€ã©ãŒã¯ãããããŸã èæ
®ããŠããŸããïŒããšãã°ãcl 18.xãŸãã¯icc 13.xããã³14.xïŒã ã
cv-qualifier-seqã䜿çšããé¢æ°ãã®åã«ã¢ã¹ã¿ãªã¹ã¯ãæ瀺çã«è¿œå ããããšãèš±å¯ãããªãå Žåããã®åããã©ã¡ãŒã¿ãŒãšããŠæå®ããéã«æé»çãªãã®ã䜿çšã§ããªãã¯ãã ãšããã§ã«æ³šææ·±ãèªè
ã¯ããããçåã«æã£ãŠããŸãã ã¯ããããããããã§ãã
ãã ããçŸæç¹ã§ã¯ãæ瀺çã«çŠæ¢ããåäžã®ã³ã³ãã€ã©ã¯ãããŸãããC ++ 03æšæºã«ã¯æ¬¡ã®ãã®ããããŸãã
8.3.5 / 4cv-qualifier-seqã¯ãééçã¡ã³ããŒé¢æ°ã®é¢æ°åãã¡ã³ããŒãžã®ãã€ã³ã¿ãŒãåç
§ããé¢æ°åããŸãã¯é¢æ°typedef宣èšã®æäžäœé¢æ°åã®äžéšã«ã®ã¿ãªããŸãã
ããã¯ã
cv-qualifier-seqã§é¢æ°åã䜿çšããããªãçãã³ã³ããã¹ãã«ã€ããŠæããŠãããŸãã ãããŠãç§ãã¡ã®ã±ãŒã¹ã¯ããã«åãŸããªãããã§ãã
ãããã£ãŠãé¢æ°åã®ãã€ã³ã¿ãŒãžã®ãå€ç°ãã«åºã¥ããŠæ§ç¯ãããã³ãŒãã¯ãã¹ãŠã®å Žåã«æ©èœããããã§ã¯ãããŸããããçŸæç¹ã§ã¯ãŸã æ©èœãããããå®å
šãªãœãªã¥ãŒã·ã§ã³ã瀺ããŸãã ããã¯ãäžçã®äžå®å
šãã«ã€ããŠã®æèã®ç³§ã«ãªããšæããŸããå®è£
çªå·1ãäœæ¥äž
ãã®å®è£
ã¯ãåã®ã»ã¯ã·ã§ã³ã§èª¬æããå¶éãèæ
®ããŠæçµåãããŸããã ã»ãšãã©ã®å ŽåïŒ100ïŒ
確信ã¯ãããŸããããããã¯å€ãã瀺ããŸãïŒããã®å®è£
ã¯æšæºã«å®å
šã«æºæ ããŠããããããã§ãæ©èœãããšããäºå®ã¯ãå°ãªããšã3ã€ã®ææ°ã®ã³ã³ãã€ã©ãŒããµããŒããããã°ã¬ããŒããéä¿¡ããçç±ãšããŠåœ¹ç«ã€ã¯ãã§ãã
åã®å®è£
ã®äž»ãªåé¡ã¯ã
cv-qualifier-seqã䜿çšããé¢æ°ã®å Žåããã€ã³ã¿ãŒã«ãã眮æãæ©èœããªããªã£ãããšã§ãã 幞ããªããšã«ãããã解決ããéµã¯ãã®åé¡ã«é ãããŠããŸãã æž¡ãããåãžã®ãã€ã³ã¿ãŒã代çšã§ãããã©ãããå€æããSFINAEãã§ãã¯ãäœæã§ããŸãã ãããã£ãŠããããäžå¯èœãªå Žåã¯ãªãã·ã§ã³ãåãæšãŠãŸãã ãã§ãã¯ã¯æ¬¡ã®ããã«ãªããŸãã
template <typename F> struct may_add_ptr { template <typename P> static char (& may_add_ptr_check(P *) )[2]; template <typename P> static char (& may_add_ptr_check(...) )[1]; enum { value = sizeof( may_add_ptr_check<F>(0) ) - 1 }; };
眮æ
P*
ãæ£ãããªãå Žåãçç¥èšå·ä»ãã®ãªãŒããŒããŒããéžæãããŸãã éžæãããªãŒããŒããŒãã«å¿ããŠãæ»ãå€ãã
sizeof
ã¯1ãŸãã¯2ãè¿ããŸãã1ãåŒããšãå€0ãŸãã¯1ãåŸãããŸããã¿ã€ããžã®ãã€ã³ã¿ãŒã眮ãæããããšãã§ããå Žåã¯1ãåŸãããäžå¯èœãªå Žåã¯0ãåŸãããŸãïŒããã¯åŸã§äœ¿çšããŸãåãããã«ïŒã ããã§ããã®ãã§ãã¯ã«åºã¥ããŠé¢æ°ãžã®ãã€ã³ã¿ãŒã®åãäœæããæ©äŒãåŸãããŸããã ç§ãã¡ã¯ããŸããŸãªæ¹æ³ã§è¡åããããšãã§ããŸã-éè² è·ãŸãã¯å°éåã«åºã¥ããŠã ãªãŒããŒããŒãã«åºã¥ããæ¹æ³ã瀺ããŸã ããããŒã¿ãã«ã§ãã
template <typename F> static typename enable_if< may_add_ptr<F>::value == 1, void (*)(typename remove_reference<F>::type *) >::type declfunc(); template <typename F> static typename enable_if< may_add_ptr<F>::value == 0, void (*)(typename remove_reference<F>::type ) >::type declfunc();
ãã®ãããåtype-ãã©ã¡ãŒã¿ãå¥ã®åã§ããé¢æ°ãžã®ãã€ã³ã¿ã圢æããŸããã ããã¯ãã¿ã€ããé¢æ°ãã«å±ããããã«èª¿æ»ããŠããã¿ã€ãã§ãã ã ãã
declfunc<F>() == void(*)( F )
次ã«ãã¿ã€ã
F
ã¯é¢æ°ã§ãã ãªã³ã¯ã®åé€ïŒ
remove_reference
ïŒãå¿
èŠã§ãããã®å Žåã次ã®å Žåã«äžçåŒãèªåçã«ååŸãããŸãã
F = R(&)(Args)
ãŸãã¯
F = T &
ãªããªã ãã¹ãŠã®çœ®æã®åŸã次ã®ã¿ã€ããæ¯èŒãããŸãã
void(*)( R(*)(Args) )
ããã³
void(*)( R(&)(Args) )
ãŸãã¯
void(*)( T )
ããã³
void(*)( T & )
ããã«å¿ããŠã ãããã®ã¿ã€ãã¯æããã«äžèŽããŸããããããå¿
èŠãªãã®ã§ãã
F
ã
R(Args)
圢åŒã®é¢æ°ã§ããå Žåããããã¯æ¯èŒãããŸã
void(*)( R(*)(Args) )
ããã³
void(*)( R(Args) )
ã
äžèšã®æšæºã®èŠå®ïŒ
8.3.5 / 3 ïŒã«åºã¥ããŠããããã®ã¿ã€ãã¯åçã§ãã
F
ã
R(Args) const
圢åŒã®é¢æ°ã§ããå Žåããããã¯æ¯èŒãããŸã
void(*)( R(Args) const )
ããã³
void(*)( R(Args) const )
ã
ãããã®ã¿ã€ããçãããå¿
èŠãªãã®ã§ãã
F = T
ïŒé¢æ°ã§ã¯ãªãïŒã®å Žåããããã¯æ¯èŒãããŸã
void(*)( T * )
ããã³
void(*)( T )
ã
ãããã®ã¿ã€ãã¯çãããããŸããããããå¿
èŠãªãã®ã§ãã
次ã«ãå®éã«ã¿ã€ããæ¯èŒããå¿
èŠããããŸãã 1ã€ãããŸããã
is_same
ã§ã¯éåžžã®
is_same
ãã§ãã¯ã䜿çšã§ããŸããã
is_function
åŒæ°ãæœè±¡åã§ããå Žåãããããã®ã³ã³ããã¹ãã§äœ¿çšãããšã³ã³ãã€ã«ãšã©ãŒãçºçããŸãã ãããã£ãŠã
is_same
ã次ã®æå³ã®SFINAEãã§ãã¯ã«çœ®ãæããŸãã
template <typename F> static char (& is_function_check( void( F ) ) )[2]; template <typename F> static char (& is_function_check( ... ) )[1];
次ã®ããããã䜿çšããŸãã
value = sizeof( is_function_check<Tp>( declfunc<Tp>() ) ) - 1;
å®å
šãªã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã template <typename Tp> struct is_function { private: template <typename F> struct may_add_ptr { template <typename X> static char (& may_add_ptr_check(X *) )[2]; template <typename X> static char (& may_add_ptr_check(...) )[1]; enum { value = sizeof( may_add_ptr_check<F>(0) ) - 1 }; }; template <typename F> static typename enable_if< may_add_ptr<F>::value == 1, void (*)(typename remove_reference<F>::type *) >::type declfunc(); template <typename F> static typename enable_if< may_add_ptr<F>::value == 0, void (*)(typename remove_reference<F>::type ) >::type declfunc(); template <typename F> static char (& is_function_check( void( F ) ) )[2]; template <typename F> static char (& is_function_check( ... ) )[1]; public: enum { value = sizeof( is_function_check<Tp>( declfunc<Tp>() ) ) - 1 }; };
ãã®ãã³ãã¬ãŒããå®éã«æ©èœããããšã確èªããããã«ããã¹ããã¯ããäœæããŸãããã
#define TEST_IS_FUNCTION(Type, R) \ std::cout << ((::is_function<Type>::value == R) ? "[SUCCESS]" : "[FAILED]") \ << " Test is_function<" #Type "> (should be [" #R "]):" \ << std::boolalpha \ << (bool)::is_function<Type>::value << std::endl
ãããŠã次ã®å®è¡
ãã¹ãã¹ã€ãŒãã struct S { virtual void f() = 0; }; int main() { typedef void f1() const; typedef void f2() volatile; typedef void f3() const volatile; TEST_IS_FUNCTION(void(int), true); TEST_IS_FUNCTION(void(), true); TEST_IS_FUNCTION(f1, true); TEST_IS_FUNCTION(void(*)(int), false); TEST_IS_FUNCTION(void(&)(int), false); TEST_IS_FUNCTION(f2, true); TEST_IS_FUNCTION(f3, true); TEST_IS_FUNCTION(void(S::*)(), false); TEST_IS_FUNCTION(void(S::*)() const, false); TEST_IS_FUNCTION(S, false); TEST_IS_FUNCTION(int, false); TEST_IS_FUNCTION(int *, false); TEST_IS_FUNCTION(int [], false); TEST_IS_FUNCTION(int [2], false); TEST_IS_FUNCTION(int **, false); TEST_IS_FUNCTION(double, false); TEST_IS_FUNCTION(int *[], false); TEST_IS_FUNCTION(int &, false); TEST_IS_FUNCTION(int const &, false); TEST_IS_FUNCTION(void(...), true); TEST_IS_FUNCTION(int S::*, false); TEST_IS_FUNCTION(void, false); TEST_IS_FUNCTION(void const, false); }
ããã§ããµã³ãã«ãšãã¹ãã®å®å
šãªã³ãŒãã確èªãã
ããã§å®è¡ã§ã
ãŸã ã ãšããã§ããã®ã³ãŒãã¯C ++ 11ã§ãæ©èœããŸãã GCC 4.4.x-6.0ãClang 3.0-3.9ãVS 2013ããã³VS 2015ã§ãã¹ããããŸãããcv
-qualifier-seq㧠F
ãžã®ãã€ã³ã¿ãè¿œå ããããšãæ€èšããŠããã³ã³ãã€ã©ããããŸãïŒicc 13.xãªã©ïŒã ãããã®ã³ã³ãã€ã©ã§ã¯æ€èšŒã¯æ©èœããŸããã
èŠæ Œã«æºæ ããå®è£
No.2
8.3.4 / 1ãæãåºããŠãã ããã é¢æ°ã¯ãé
åãäœæã§ããªãæ°å°ãªãã¿ã€ãã®1ã€ã§ãããšè¿°ã¹ãŸããã åã®æ¹æ³ã¯ãã¹ãŠæ確ã§ã¯ãªãã®ã§ãããã§ãã£ãšå¹žéãåŸ
ã£ãŠããã®ã§ã¯ãªãã§ããããïŒ äœæã§ããªãåã®é
åãããäžåºŠãªã¹ãããŸãã
- ãªã³ã¯
void
- æœè±¡ã¯ã©ã¹
- æ©èœ
ãããã£ãŠãã¿ã¹ã¯ã2ã€ã®æ®µéã«åããããšãã§ããŸãã åæ§ã®åäœãæã€ä»ã®ã¿ã€ããé€å€ããæå®ãããã¿ã€ãã®é
åãäœæã§ãããã©ããã決å®ããSFINAEãã§ãã¯ãèšè¿°ããŸãã æåã«ãæœè±¡ã¯ã©ã¹ãé€å€ããŸãã ãã¹ãŠã®ã¯ã©ã¹ãäžåºŠã«åãé€ãæãç°¡åãªæ¹æ³ã§ããã ãããè¡ãã«ã¯ãã¡ã¿æ©èœãå¿
èŠã§ãã
template <typename Tp> struct is_class;
ããã§ããªã³ã¯ãšvoidãèæ
®ããé€å€ããå¿
èŠããããŸãã ããã«ã¯ã次ã®2ã€ã®ãã³ãã¬ãŒãã䜿çšããŸãã
template <typename Tp> struct is_lvalue_reference; template <typename Tp> struct is_void;
ããã¯ãã¹ãŠã®ããã§ãããäœããæ¬ ããŠããŸãã å®éãé
åã®èŠçŽ ã«ãªããªãå¥ã®åããããŸã-ããã¯
æªç¥ã®å¢çã®é
åïŒæªç¥ã®ãµã€ãº
T[]
é
åïŒã§ãã ãŸãããããåãé€ãå¿
èŠããããŸãã ååãšããŠãäžåºŠã«ãã¹ãŠã®ã¢ã¬ã€ãèŠåŽããŠãµããã«ãããããšã¯ã§ããŸããã
template <typename Tp> struct is_array;
ãããã®ã¡ã¿é¢æ°ã®å®è£
ã¯ã
ããã§èŠã€ããããšãã§ããŸããããšãã°ãboostããååŸããããšãã§ããŸãã
次ã«ãã¡ã€ã³ãã³ãã¬ãŒããäœæããŸãã
template <typename Tp> struct is_function { private: template <typename F> static char (& check_is_function( ... ) )[2]; template <typename F> static char (& check_is_function( F (*)[1] ) )[1]; public: enum { value = !is_class<Tp>::value && !is_void<Tp>::value && !is_lvalue_reference<Tp>::value && !is_array<Tp>::value && (sizeof( check_is_function<Tp>(0) ) - 1) }; };
ãé
åãžã®ãã€ã³ã¿ãåã®å®çŸ©ãä»ããŠãåãé
åã®èŠçŽ ã«ãªãåŸããã©ããã確èªããŸããåã®èŠçŽ ã¯ã
check_is_function
é¢æ°ã®ãã©ã¡ãŒã¿ãŒãšããŠãã¹ããããŸãã 眮æã倱æããå Žåãã¿ã€ã
F
ã¯é¢æ°ã§ãã
ãã¹ããšããŠã
å®è£
1ãã以åã®ã»ãããååŸããŸãã å®å
šãªã³ãŒãã¯
ããã§è¡šç€ºã§ãã
ããã§å®è¡ã§ã
ãŸã ã ãã®å®è£
ã¯æšæºã«å®å
šã«æºæ ããŠãããã»ãšãã©ã®ã³ã³ãã€ã©ã§åäœããå¯èœæ§ãæãé«ããªããŸãã ãã®ã³ãŒãã¯C ++ 11ã§ãæ©èœããŸããå³èŸºå€ãªã³ã¯ãè¿œå ã§é€å€ããã ãã§ãã
çµè«ã®ä»£ããã«
1ïŒ
cv-qualifier-seqãããã€ã³ã¿ãŒãžã®é¢æ°ã®äžæ£ãªããã¢ãŒã·ã§ã³ã«é¢ãã3ã€ã®ãã°ã¬ããŒããéä¿¡ããŸããã
Clangã®ãµããŒã ã
GCCããµããŒãããŠããŸãã
VSã®ãµããŒããæ¢ã«è¿°ã¹ãããã«ã100ïŒ
確信ã¯ãããŸããããããããã®åé¡ã«é¢ããéçºè
ã®æèŠãåŸãå¯äžã®æ¹æ³ã§ãã
2ïŒç§ã®
githubã«ããå®å
šãªã³ãŒãã¯ãèšäºã«èšèŒãããŠããã³ãŒããšã¯å€å°ç°ãªããŸãã ããã§ã¯ãããã€ãã®è©³çŽ°ãšãããŒãæå³çã«çç¥ãããŸããã
2.1ïŒcv-qialifier-seqã䜿çšããŠé¢æ°ã®ã¿ã€ãããã詳现ã«èª¬æããããã«äŸé ŒãããŸããããã®åã䜿çšããŠç©ºãé¢æ°ã宣èšã§ããªãããšã¯æããã§ãã
cv-qialifier-seqã¯ãããæããŸãïŒ9.3.1 / 3ãåç
§ïŒã
ããã§ã¯ã©ã®ãããªç¶æ³ã§æ©èœããŸããïŒ æšæºã§ã¯ã次ã®å Žåã«ãããèš±å¯ããŠããŸãã
8.3.5 / 7宣èšåã«cv-qualifier-seqãå«ãŸããé¢æ°åã®typedefã䜿çšãããŸãã
ééçã¡ã³ããŒé¢æ°ã®é¢æ°åã宣èšããã ãã§ã
ã¡ã³ããŒãžã®ãã€ã³ã¿ãåç
§ããããå¥ã®é¢æ°typedef宣èšã®ãããã¬ãã«ã®é¢æ°åã宣èšããŸãã
[äŸïŒ typedef int FIC(int) const; FIC f;
âçµããã®äŸ]
ã€ãŸã
cv-qualifier-seqã§é¢æ°åã®typedefã䜿çšããããšãã§ããŸãïŒ
- ã¡ã³ããŒé¢æ°ã宣èšãã
- ã¡ã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã圢æãã
- å¥ã®é¢æ°åã®typedef宣èšã§æäžäœåãšããŠäœ¿çšããŸãã
åŸè
ã®ã±ãŒã¹ã¯ããªãé§ãããã£ãŠããŸãïŒå¥ã®æ©èœã®æå³ã¯ïŒïŒã æ¯èŒã®ããã«ãæåŸã®ãã©ããããåŒçšããŸãã
8.3.5 / 6cv-qualifier-seqãŸãã¯ref-qualifierïŒtypedef-nameïŒ7.1.3ã14.1ïŒã§æå®ãããåãå«ãïŒãæã€é¢æ°åã¯ã次ã®ããã«ã®ã¿è¡šç€ºãããŸãïŒ
ïŒ6.1ïŒ-ééçã¡ã³ããŒé¢æ°ã®é¢æ°ã¿ã€ãã
ïŒ6.2ïŒ-ã¡ã³ããŒãžã®ãã€ã³ã¿ãŒãåç
§ããé¢æ°åã
ïŒ6.3ïŒ-é¢æ°typedef宣èšãŸãã¯ãšã€ãªã¢ã¹å®£èšã®ãããã¬ãã«é¢æ°åã
ïŒ6.4ïŒ-åãã©ã¡ãŒã¿ãŒã®ããã©ã«ãåŒæ°ã®åIDïŒ14.1ïŒããŸãã¯
ïŒ6.5ïŒ-åãã©ã¡ãŒã¿ãŒïŒ14.3.1ïŒã®ãã³ãã¬ãŒãåŒæ°ã®åIDã
[äŸïŒ typedef int FIC(int) const; FIC f;
-çµäºäŸ]
åæããŸããããã¯ã¯ããã«ç解ããããã§ãïŒ6.3ã«æ³šæããŠãã ããããããã¬ãã«é¢æ°ã®
typedef
cv-qualifier-seqã®äœ¿çšãåæ³åããä»ã®é¢æ°
ã®ã¿ã§ã¯ãããŸããïŒã ãã®ã¿ã€ããé¢æ°ãã©ã¡ãŒã¿ãŒãšããŠäœ¿çšã§ããããã«ãªã£ããšããäºå®ã¯ãç§ãäœæãããã°ã¬ããŒãã®äž»é¡ã§ãã ããã«ããã®å Žåããããã®ã¿ã€ãã¯ãã€ã³ã¿ãŒã«é²ãããããããçŠæ¢ãããŸãïŒ
8.3.1 / 4 ïŒã
ããã§å€æŽãæ¯èŒã
ãŸã ã ãŸãã誰ãã
ãã®è³æã«èå³ãæã€å¯èœæ§ããããŸãã
3ïŒãæž
èŽããããšãããããŸãã:)