// <ã³ãŒã>int main
ïŒ ïŒ{constexpr
int a
= f
ïŒ ïŒ ;constexpr
int b
= f
ïŒ ïŒ ;static_assert
ïŒ a
ïŒ= b
ã "fail" ïŒ ;}äžèšã®ãã©ã°ã¡ã³ãã«ã³ã¡ã³ãã®ä»£ããã«
fïŒïŒã®å®çŸ©ãæ¿å
¥ããŠ
ã aãb以å€ã®å€ãååŸããããš
ã¯å¯èœã§ããïŒ
ããã¡ããããã§ã¯ãããŸããïŒãããªãã¯å°ãèããŠèšãã å®éãäž¡æ¹ã®å€æ°ã¯
constexpræå®åã§å®£èš
ãããŸã ãã€ãŸãã
fïŒïŒã
constexpré¢æ°ã§ãªããã°ãªããŸããã
constexpré¢æ°ã¯ã³ã³ãã€ã«æã«å®è¡ã§ããããšã誰ããç¥ã£ãŠããŸãããã®çµæãããã°ã©ã ã®ã°ããŒãã«ãªç¶æ
ã«äŸåããããããã°ã©ã ãå€æŽãããããã¹ãã§ã¯ãããŸããïŒèšãæãããšã
ãããã¯cleanã§ãªããã°ãªããŸãã ïŒã æž
æµåºŠãšã¯ãé¢æ°ãåãåŒæ°ã§åŒã³åºããããã³ã«åãå€ãè¿ãå¿
èŠãããããšãæå³ããŸãã
fïŒïŒã¯åŒæ°ãªãã§äž¡æ¹ã®æéã§åŒã³åºããããããå€æ°
aãš
bã«å²ãåœãŠãããåãå€ãäž¡æ¹ã®æéã§è¿ãå¿
èŠããããŸã...
1é±éåãç§ã¯ãããçå®ã§ããããšãç¥ã£ãŠããã®ã§ãæªå®çŸ©ã®åäœãé¿ããŠãäžèšã®ã¹ããããã§
static_assertãæž¡ãããšã¯äžå¯èœã ãšæ¬åœã«æã£ãŠããŸããã
ç§ã¯ééã£ãŠããŸããã
å
容
å
責äºé
ïŒãã®èšäºã§èª¬æããææ³ã¯ããC ++ã®æãæ·±ã¿ã«æ²¡é ããå¥ã®ããªãããŒãªããã¯ããšäœçœ®ä»ããããŠããŸãã æåã«ãã¹ãŠã®èœãšãç©ŽïŒä»¥äžã®èšäºã§è©³çŽ°ã«èª¬æããŸãïŒãåŠç¿ããã«ãå®çšŒåç°å¢ã§äœ¿çšããããšã¯ãå§ãããŸããã
å
責äºé
ã¯ãä»ã®ãµã€ãã§ãã®èšäºã®ã³ã¡ã³ããèªãã åŸã«è¿œå ããããã®ã§ããã®ç®çã®èª€è§£ãèŠã€ããŸããã ç§ã¯ããªãã®å¯å®€ã®å€ã§èª¬æããããã¯ããã¯ã䜿çšããããšãæ¿èªããŸããïŒãã®ãããªäœ¿çšã®çµæãèæ
®ããªãã§ïŒã
ãªããããå¿
èŠãªã®ã§ããããïŒ
èšäºã®åé ã§æèµ·ãããåé¡ã解決ããããã³ã³ãã€ã«ããã»ã¹ã«å¯å€ç¶æ
ãæ£åžžã«è¿œå ã§ããŸãïŒèšãæãããšãåœä»€åã¡ã¿ããã°ã©ã ãèšè¿°ã§ããŸãïŒã
ã泚æ transïŒå¯å€å®æ°å®æ°ããå€æ°ããšããŠäœ¿çšãããšãã¡ã¿ããã°ã©ã ã®åœä»€æ§ãç°¡åã«è¿œå ã§ãããšèªè
ã¯äž»åŒµãããããããŸããã ãããã£ãŠãåé¡ã解決ããã«ã¯ã ïŒdefine fïŒïŒ__COUNTER__ãŸãã¯ãã®ãããªãã®ã䜿çšã§ããŸãã
æ®å¿µãªãããããã¯æãåçŽãªå Žåã«ã®ã¿æ©èœããŸããããã¯ãããªããã»ããµãããã°ã©ã ããã¹ãå
ã§ãã¯ãã«ééãããšããã«ãã¯ããå±éããèšèªèªäœã®æ§ææ§é ãç¡èŠããããã§ãã ãããã£ãŠãã¡ã¿é¢æ°ã®ã€ã³ã¹ã¿ã³ã¹åã®é åºãéèŠã«ãªãããå€æ°ãäžåºŠèªã¿åã£ãŠå€æŽãã以å€ã®äœããå¿
èŠã«ãªããšããã«ããã¯ãã¯ãã®èœåã§åœ¹ã«ç«ããªããªããŸãã
äžèŠãããã¯å°ãããŠç¡éªæ°ãªæŠå¿µã®ããã«æãããããããŸãããããã®èšäºã§èª¬æããææ³ã䜿çšãããšã以åã¯éåžžã«è€éãªã³ãŒããå¿
èŠãšãããããŸã£ãã解決ã§ããªãã£ãå€ãã®åé¡ã解決ã§ããŸãã
äŸïŒ
ã³ã³ãã€ã«æã«ãŠã³ã¿ãŒ
C1 = ... ã䜿çšããŸãã
int constexpr a = C1 :: next ïŒ ïŒ ; // = 1
int constexpr b = C1 :: next ïŒ ïŒ ; // = 2
int constexpr c = C1 :: next ïŒ ïŒ ; // = 3
ã³ã³ãã€ã«æã¡ã¿ã¿ã€ãã³ã³ãããŒ
LX = ... ã䜿çšããŸãã
LX :: push < void ã void ã void ã void > ïŒ ïŒ ;
LX :: set < 0 ã ã¯ã©ã¹ Hello > ïŒ ïŒ ;
LX :: set < 2 ã ã¯ã©ã¹ World > ïŒ ïŒ ;
LX :: pop ïŒ ïŒ ;
LX :: å€ <> x ; // type_list <class Helloãvoidãclass World>
ä»ã®ã¢ã€ãã¢
äºåæ
å ±
泚ïŒãã®ããŒãã§ã¯ãåé¡ã®è§£æ±ºã«é¢é£ããæè¡çãªåŽé¢ã«ã€ããŠè©³ãã説æããŸãã ãããã£ãŠãæãçµéšè±å¯ãªïŒãŸãã¯ãã£ãã¡ãªïŒèªè
ã¯ãããã¹ãããã§ããŸãã ãèåã®ããã ãã«ããã«ããå Žåã¯ãããã«æ±ºå®ã«é²ã¿ãŸãã
泚ïŒå°ãªããšãããœãªã¥ãŒã·ã§ã³ã³ãŒããæ£ç¢ºã«ã©ã®ããã«ããªãæ©èœããã®ãïŒãããŠæšæºã®èŠ³ç¹ããã¯åæ³ã§ãïŒã«èå³ãããå Žåã¯ãå°ãªããšããã®éšåããã£ãšèªãããšããå§ãããŸãã
åéããŒã¯ãŒã
C ++ã®ãã¬ã³ãã·ããé¢ä¿ã¯ãå¥ã®ãšã³ãã£ãã£ã«ãã®
ãã©ã€ããŒãã¡ã³ããŒããã³
ä¿è·ãããã¡ã³ããŒãžã®ã¢ã¯ã»ã¹ãæäŸããã ãã§ãªã䜿çšã§ããŸãã 次ã®ïŒéåžžã«åçŽãªïŒäŸã«ã€ããŠèããŸãã
ã¯ã©ã¹ A ;
ãã€ãã¿ããïŒ A ïŒ ïŒ ;
ã¯ã©ã¹ A
{
å人 ãã€ãã¿ããïŒ A ïŒ ïŒ ;
intã¡ã³ããŒ;
} ;
ãã€ãã¿ããïŒ A ïŒ ref ïŒ
{
refã ã¡ã³ã㌠= 123 ; // OKã `void touchïŒAïŒïŒ`ã¯ã¯ã©ã¹Aã®å人ã§ã
}
int main ïŒ ïŒ
{
A a ; aã ã¡ã³ã㌠= 123 ; //ç¡å¹ãã¡ã³ããŒãA ::ã¡ã³ããŒããã©ã€ããŒã
A b ; ã¿ããïŒ b ïŒ ;
}
æåã«ãã°ããŒãã«ã¹ã³ãŒãã§
voidã¿ããïŒAïŒïŒé¢æ°ã宣èšãã次ã«ã¯ã©ã¹
Aã« ãã¬ã³ããªã«å®£èšããæåŸã«ã°ããŒãã«ã¹ã³ãŒãã§
å®çŸ©ããŸãã
åãæåãåããŠã次ã®äŸã®ããã«ãäœãå€æŽããã«ãã¯ã©ã¹
Aå
ã«
void touchïŒAïŒïŒã®å®£èšãšå®çŸ©ãçµã¿åãããŠçŽæ¥é
眮ã§ããŸãã
ã¯ã©ã¹ A
{
ãã¬ã³ã ãã€ãã¿ããïŒ A ïŒ ref ïŒ
{
refã ã¡ã³ã㌠= 123 ;
}
intã¡ã³ããŒ;
} ;
int main ïŒ ïŒ
{
A b ; ã¿ããïŒ b ïŒ ; // OK
}
friendã䜿çšããããã®ããã2ã€ã®ã¢ãããŒããå®å
šã«åç
ã§ã¯ãªãããšã¯éåžžã«éèŠã§ãïŒãã ãããã®ç¹å®ã®ã±ãŒã¹ã§ã¯ããã§ããããã«æããããããããŸããïŒã
æåŸã®äŸã§ã¯ã
ãã€ãã¿ããïŒAïŒïŒã¯ãã¯ã©ã¹
Aãå²ãæãè¿ãåå空éã®ã¹ã³ãŒãã«æé»çã«é
眮ãããŸããã
Koenigæ€çŽ¢ ïŒADLïŒã«ãã£ãŠã®ã¿ã¢ã¯ã»ã¹ã§ããŸãã
ã¯ã©ã¹ A
{
å
¬é ïŒ
A ïŒ int ïŒ ;
ãã¬ã³ã ãã€ãã¿ããïŒ A ïŒ { ... }
} ;
int main ïŒ ïŒ
{
A b = 0 ; ã¿ããïŒ b ïŒ ; // OKã `void touchïŒAïŒ`ã¯ADLãä»ããŠæ€åºãããŸã
ã¿ããïŒ 0 ïŒ ; //ééã£ãŠããŸããåŒæ°ã®å㯠`int`ã§ãADLã¯ã¯ã©ã¹ãã¹ãã£ã³ããŸãã` A`
}
以äžã®æšæºããã®æç²ã¯äžèšãç¹°ãè¿ããŸãããè¡éã«æžãããŠããããšã«éäžããŠã»ããã§ãïŒåæ§ã«éèŠã ããã§ãïŒïŒ
7.3.1.2/3åå空é ã¡ã³ããŒå®çŸ© [namespace.memdef] p3åå空éå
ã§æåã«å®£èšãããåååã¯ããã®åå空éã®ã¡ã³ããŒã§ãã éããŒã«ã«ã¯ã©ã¹å
ã®ãã¬ã³ã宣èšãæåã«ã¯ã©ã¹ãé¢æ°ãã¯ã©ã¹ãã³ãã¬ãŒãããŸãã¯é¢æ°ãã³ãã¬ãŒãã宣èšããå Žåããããã¯æãè¿ãã«ããåå空éã®ã¡ã³ããŒã«ãªããŸãã ãã¬ã³ã宣èšã ãã§ã¯ãé修食ïŒ3.4.1ïŒãŸãã¯ä¿®é£ŸïŒ3.4.3ïŒã®ååæ€çŽ¢ã§ååã衚瀺ãããããšã¯ãããŸããã
ãã¬ã³ã宣èšãä»ããŠå
¥åãããååã¯ããã®å®£èšã眮ãããŠããã¯ã©ã¹ã®ååãšãå®éã«ã¯ãã®ã¯ã©ã¹ãšã®é¢ä¿ã«é¢ä¿ããŠããå¿
èŠãããããšã¯ã©ãã«ãèšèŒãããŠããªãããšã«æ³šæããŠãã ããã
#include <iostream>
ã¯ã©ã¹ A
{
å
¬é ïŒ
A ïŒ int ïŒ { }
å人 ãã€ã f ïŒ A ïŒ ;
} ;
ãã€ã g ïŒ A ïŒ ;
ã¯ã©ã¹ B
{
åé ãã€ã f ïŒ A ïŒ
{
std :: cout << "hello worldïŒ" << std :: endl ;
}
ã¯ã©ã¹ C
{
åé ãã€ã g ïŒ A ïŒ
{
std :: cout << "ïŒdlrow olleh" << std :: endl ;
}
} ;
} ;
int main ïŒ ïŒ
{
A a ïŒ 0 ïŒ ;
f ïŒ a ïŒ ;
g ïŒ 1 ïŒ ;
}
ãããã£ãŠã
fïŒïŒã¯ã¯ã©ã¹
Bãš
ã¯é¢ä¿ããããŸããããã ããã¯ã©ã¹
B㯠ããã®å
éšã§çŽæ¥
ãã¬ã³ããšããŠå®çŸ©ãããŠãããšããäºå®ãé€ãããã®ãããªã³ãŒãã¯çµ¶å¯Ÿã«æ£ããã§ãã
泚ïŒãããã®èæ
®äºé
ã¯éåžžã«ç°¡åã«æãããããããŸããããäœãèµ·ãã£ãŠããã®ãçåãããå Žåã¯ãã³ã³ãã€ã©ãŒãèŠã€ããŠäžèšã®ã¹ãããããè©ŠããŠã¿ãããšããå§ãããŸãã
å®æ°åŒã®ã«ãŒã«
constexprã«é¢é£ããã«ãŒã«ã¯å€æ°ããããã®å°å
¥ãããå³å¯ãã€è©³çŽ°ã«ããããšãã§ããŸãããç°¡åã«èª¬æããŸãã
- ãªãã©ã«åã¯ã constexpr-å€æ°ãšconstexpr -functionsã«ãã£ãŠè¿ãããå€ãæã€ããšãã§ããåã§ãã ãããã®åã¯ãã¹ã«ã©ãŒåïŒç®è¡åããã€ã³ã¿ãŒãããã³åæïŒãåç
§åãããã³ãã®ä»ã®åã§ãã ããã«ãç¹å®ã®å¶éïŒ constexprã³ã³ã¹ãã©ã¯ã¿ãŒ ã ç°¡æãã¹ãã©ã¯ã¿ããã¹ãŠã®ããŒã¿ã¡ã³ããŒã®åãããã³åºåºã¯ã©ã¹ã¯ãªãã©ã«ïŒãæºããã¯ã©ã¹ããªãã©ã«åã§ãã
- constexpræå®åã§å®£èšãããå€æ°ã¯ãªãã©ã«åã§ãããå®æ°åŒã§ããã«åæåãããå¿
èŠããããŸãã
- constexpræå®åã§å®£èšãããé¢æ°ã¯ããªãã©ã«åã®ã¿ããã©ã¡ãŒã¿ãŒãšããŠåãå
¥ãã å®æ°åŒã§çŠæ¢ãããŠããæ§é ïŒããšãã°ã constexpr以å€ã®é¢æ°ã®åŒã³åºãïŒãå«ããããšã¯ã§ããŸããã
- å®æ°ã¯ãããããèŠã€ãããªãåŒã§ãã
- åŒã³åºãã¯constexpr-é¢æ°ã§ã¯ãããŸããã
- ãŸã å®çŸ©ãããŠããªãé¢æ°ã®åŒã³åºãã
- å®æ°åŒã§ã¯ãªãåŒæ°ã䜿çšããé¢æ°åŒã³åºãã
- å®æ°åŒã«ãã£ãŠåæåããããçŸåšã®å®æ°åŒã®èšç®ãå§ãŸãåã«ååšãå§ããå€æ°ãžã®ã¢ã¯ã»ã¹ã
- æªå®çŸ©ã®åäœãåŒãèµ·ããæ§ç¯ç©ã
- ã©ã ãåŒãäŸå€ãããã³ãã®ä»ã®æ§é ã
泚ïŒãã®ãªã¹ãã¯äžå®å
šã§å³å¯ã§ã¯ãããŸããããã»ãšãã©ã®å Žåã«constexprãšã³ãã£ãã£ãšå®æ°åŒãã©ã®ããã«åäœãããã瀺ããŠããŸãã
å®æ°åŒã®æäœã®ãã¹ãŠã®åŽé¢ã詳现ã«æ€èšãã代ããã«ãåŒã³åºãæã«ãŸã å®çŸ©ãããŠããªãé¢æ°åŒã³åºããå®æ°åŒã«å«ããªãããã«ããèŠåã«çŠç¹ãåœãŠãŸãã
constexpr int f ïŒ ïŒ ;
ãã€ãã€ã³ãã€ã¬ã¯ã·ã§ã³ïŒ ïŒ ;
int main ïŒ ïŒ
{
constexpr int n = f ïŒ ïŒ ; //ç¡å¹ã `int fïŒïŒ`ã¯ãŸã å®çŸ©ãããŠããŸãã
ã€ã³ãã€ã¬ã¯ã·ã§ã³ïŒ ïŒ ;
}
constexpr int f ïŒ ïŒ
{
0ã è¿ã ãŸã ã
}
ç¡å¹ãªéæ¥æå®ïŒ ïŒ
{
constexpr int n = f ïŒ ïŒ ; // OK
}
ããã§ã¯ã
constexpr -function int fïŒïŒã
å®£èš ãããŠããŸããã
mainã§
å®çŸ©ãããŠããŸãã
ã ãã€ã³
ãã€ã¬ã¯ã·ã§ã³å
ã«å®çŸ©ããããŸãïŒããã£ãéå§ãããŸã§ã«ã€ã³
ãã€ã¬ã¯ã·ã§ã³å®çŸ©ããã§ã«æäŸãããŠããããïŒã ãããã£ãŠã
ã€ã³ ãã€ã¬ã¯ã·ã§ã³å
ã§ã¯ã
constexpré¢æ°
fïŒïŒã®åŒã³åºãã¯å®æ°åŒã«ãªãã
nã®åæåã¯æ£ãããªããŸãã
åŒãå®æ°ã§ããããšã確èªããæ¹æ³
ç¹å®ã®åŒã
å®æ°ã§ãããã©ããã確èªããæ¹æ³ã¯ããã€ããããŸããããããã®ããã€ãã¯ä»ã®ãã®ãããå®è£
ãå°é£ã§ãã
çµéšè±å¯ãªC ++éçºè
ã¯ãããã§
SFINAE ïŒçœ®æã®å€±æã¯ãšã©ãŒã§ã¯ãªãïŒã®æŠå¿µãããŸãé©çšããæ©äŒãããã«èŠãŠãæ£ããã§ãããã ããããSFINAEãæäŸããèœåã¯ãããªãè€éãªã³ãŒããèšè¿°ããå¿
èŠæ§ãšçµã³ã€ããŠããŸãã
ã泚æ ãããïŒããšãã°ãconstexpr int x = 7 ;
ãã³ãã¬ãŒã < typename >
std :: false_type isConstexpr ïŒ ... ïŒ ;
template < typename T ã T test = ïŒ 15 * 25 - x ïŒ > //ãã¹ãåŒ
std :: true_type isConstexpr ïŒ T * ïŒ ;
constexpr bool value = std :: is_same < decltype ïŒ isConstexpr < int > ïŒ nullptr ïŒ ïŒ ã std :: true_type > :: value ; // true
noexceptæŒç®åã䜿çšããŠåé¡ã解決ããæ¹ãã¯ããã«ç°¡åã§ãã ãã®æŒç®åã¯ãäŸå€ãã¹ããŒã§ããªãåŒã«å¯ŸããŠ
trueãè¿ããããã§ãªãå Žåã¯
falseãè¿ã
ãŸã ã ç¹ã«ããã¹ãŠã®å®æ°åŒã¯äŸå€ãã¹ããŒããªããšèŠãªãããŸãã ããã§ãã¬ã€ããŸãã
constexpr int f ïŒ ïŒ ;
ãã€ãã€ã³ãã€ã¬ã¯ã·ã§ã³ïŒ ïŒ ;
int main ïŒ ïŒ
{
// `fïŒïŒ`ã¯å®æ°åŒã§ã¯ãããŸããã
//ãã®å®çŸ©ãæ¬ èœããŠããé
constexpr bool b = noexcept ïŒ f ïŒ ïŒ ïŒ ; // false
}
constexpr int f ïŒ ïŒ
{
0ã è¿ã ãŸã ã
}
ç¡å¹ãªã€ã³ãã€ã¬ã¯ã·ã§ã³ïŒ ïŒ
{
//ãããŠä»
constexpr bool b = noexcept ïŒ f ïŒ ïŒ ïŒ ; // true
}
泚ïŒçŸåšã clangã«ã¯ãã°ãå«ãŸããŠããŸããããã¯ããã§ãã¯ãããåŒãå®æ°ã§ãã£ãŠãã noexceptãtrueãè¿ããªãããã§ã ã åé¿çã¯ããã®èšäºã®ä»é²ã«èšèŒãããŠããŸãã
ãã³ãã¬ãŒãã®ã€ã³ã¹ã¿ã³ã¹åã®ã»ãã³ãã£ã¯ã¹
C ++æšæºã«ãã»ãšãã©ã®ããã°ã©ãã«ãšã£ãŠæ¬åœã®ææŠãããããéšåãããå Žåãããã¯ééããªããã³ãã¬ãŒãã«é¢é£ããŠããŸãã ããã§ãã³ãã¬ãŒãã®ã€ã³ã¹ã¿ã³ã¹åã®ããããåŽé¢ãæ€èšããããšã«ããå Žåãèšäºã¯éåžžã«å€§ãããªããå°ãªããšãæ°æéã¯èªã¿ç¶ããããšã«ãªããŸãã
ããã¯ç§ãã¡ãç®æããŠããããšã§ã¯ãªãã®ã§ã代ããã«ãåé¡ã®è§£æ±ºçãã©ã®ããã«æ©èœããããç解ããããã«å¿
èŠãªã€ã³ã¹ã¿ã³ã¹åã®åºæ¬ååã«ã€ããŠã®ã¿ã話ãããããšããŸãã
泚ïŒãã®ã»ã¯ã·ã§ã³ã®å
容ã¯ããã³ãã¬ãŒããã€ã³ã¹ã¿ã³ã¹åããããã®å®å
šãªãªãã¡ã¬ã³ã¹ã§ã¯ãªãããšã«æ³šæããŠãã ããã ããã«èšèŒãããŠããã«ãŒã«ã«ã¯äŸå€ããããŸããããã«ãèšäºã®ç¯å²ãè¶
ããŠããããã€ãã®äºå®ãæå³çã«çç¥ããŸããã
åºæ¬åå
æå°ã®èŸæž- ãã³ãã¬ãŒãã®ç¹æ®åã¯ããã³ãã¬ãŒããã©ã¡ãŒã¿ãç¹å®ã®åŒæ°ã«çœ®ãæããããšã«ããããã³ãã¬ãŒãããååŸãããå®è£
ã§ãã ãã³ãã¬ãŒã<typename T>ã¯ã©ã¹Foo-ãã³ãã¬ãŒãã Foo <int>ã¯åœŒã®å°éåéã§ãã ããã°ã©ãã¯ããã®åäœãäžè¬åããããã®ãšç°ãªãããšãå¿
èŠãªå Žåãç¹å®ã®åŒæ°ã»ããã«å¯ŸããŠãã³ãã¬ãŒãã®å®å
šãŸãã¯éšåçãªç¹æ®åãåå¥ã«æäŸã§ããŸãã é¢æ°ãã³ãã¬ãŒãã§ã¯éšåçãªç¹æ®åã¯äœ¿çšã§ããŸããã
- ãã³ãã¬ãŒãç¹åã®ã€ã³ã¹ã¿ã³ã¹ -æ±çšãã³ãã¬ãŒãã³ãŒãããç¹æ®åã³ãŒããã³ã³ãã€ã©ãŒã§ååŸããŸãã ç°¡æœã«ããããã«ã圌ãã¯ãã°ãã°ç¹å®ã®åŒæ°ã䜿çšããŠãã³ãã¬ãŒããã€ã³ã¹ã¿ã³ã¹åããããšã«ã€ããŠè©±ãããç¹æ®åããšããèšèãçç¥ããŸãã
- ã€ã³ã¹ã¿ã³ã¹åã¯æ瀺çãŸãã¯æé»çã§ãã æ瀺çã«ã€ã³ã¹ã¿ã³ã¹åããå Žåãããã°ã©ããŒã¯ç¹å®ã®åŒæ°ã䜿çšããŠãã³ãã¬ãŒããã€ã³ã¹ã¿ã³ã¹åããå¿
èŠãããããšãã³ã³ãã€ã©ãŒã«åå¥ã«éç¥ããŸããäŸïŒ template class Foo <int> ããã«ãå¿
èŠã«å¿ããŠãã³ã³ãã€ã©ãŒã¯ããèªäœã§ç¹æ®åãæé»çã«ã€ã³ã¹ã¿ã³ã¹åã§ããŸãã
以äžã¯ãã¿ã¹ã¯ã«æãçŽæ¥é¢ä¿ããååã®ç°¡æœãªãªã¹ãã§ãã
- ãã³ãã¬ãŒãïŒã¯ã©ã¹ãšé¢æ°ã®äž¡æ¹ïŒã®ç¹æ®åã¯ã以åã«æ瀺çã«ã€ã³ã¹ã¿ã³ã¹åãããŠãããããŠãŒã¶ãŒã察å¿ããå®å
šãªç¹æ®åãæäŸããŠããªãå Žåã«ã®ã¿ãæé»çã«ã€ã³ã¹ã¿ã³ã¹åã§ããŸã ã
- é¢æ°ãã³ãã¬ãŒãã®ç¹æ®åã¯ããã®å®çŸ©ãå¿
èŠãšããã³ã³ããã¹ãã§èšåãããŠããå Žåãæé»çã«ã€ã³ã¹ã¿ã³ã¹åãããæåã®æ®µèœãæºããããŸãã
- ã¯ã©ã¹ãã³ãã¬ãŒãã®ç¹æ®åã¯ã å®å
šã«å®çŸ©ããã ïŒå®å
šãªïŒåãå¿
èŠãšããã³ã³ããã¹ãã§èšåãããŠããå ŽåããŸãã¯ãã®å®å
šæ§ãããã°ã©ã ã®ã»ãã³ãã£ã¯ã¹ã«åœ±é¿ããå Žåã«æé»çã«ã€ã³ã¹ã¿ã³ã¹åããããã®å ŽåïŒäž¡æ¹ã®å ŽåïŒæåã®æ®µèœãæºããããŸãã
- ã¯ã©ã¹ãã³ãã¬ãŒãã®ã€ã³ã¹ã¿ã³ã¹åã«ããããã®ã¡ã³ããŒãã¹ãŠã®å®£èšãæé»çã«ã€ã³ã¹ã¿ã³ã¹åãããŸãããã¡ã³ããŒã以äžã®å Žåãé€ãã å®çŸ©ã¯ã€ã³ã¹ã¿ã³ã¹åãããŸããã
- éçã¡ã³ããŒå€æ°ããã®å Žåã宣èšãã€ã³ã¹ã¿ã³ã¹åãããŸããã
- ã¹ã³ãŒããŸãã¯å¿åçµåã®ãªãåæããã®å Žåã宣èšãšå®çŸ©ã®äž¡æ¹ãã€ã³ã¹ã¿ã³ã¹åãããŸãã
- ã¡ã³ããŒå®çŸ©ã¯ãèŠæ±ããããšãã«æé»çã«ã€ã³ã¹ã¿ã³ã¹åãããŸããããã以åã§ã¯ãããŸããã
- ã¯ã©ã¹ãã³ãã¬ãŒãã®ç¹æ®åã«ãã¬ã³ã宣èšãå«ãŸããŠããå Žåããããã®ãã¬ã³ãã®ååã¯ãæ瀺çãªç¹æ®åãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã«é
眮ãããŠãããã®ããã«ããã«èæ
®ãããŸãã
ã€ã³ã¹ã¿ã³ã¹åãã€ã³ã
ã¯ã©ã¹ãŸãã¯é¢æ°ã®ãã³ãã¬ãŒãã®ç¹åãèšåãããŠããã³ã³ããã¹ãããã®ã€ã³ã¹ã¿ã³ã¹åãå¿
èŠãšãããšãã¯ãã€ã§ãããããã
ã€ã³ã¹ã¿ã³ã¹åãã€ã³ã ïŒå®éã«ã¯ãæ±çšãã³ãã¬ãŒãã³ãŒãããç¹æ®åã³ãŒããçæãããšãã«ã³ã³ãã€ã©ãååšã§ããå Žæã®1ã€ã決å®ããŸãïŒã
ãã¹ãããããã³ãã¬ãŒãã®å Žåãå€éšãã³ãã¬ãŒã
Yã®ãã©ã¡ãŒã¿ãŒã«äŸåããã³ã³ããã¹ãã§å
éšãã³ãã¬ãŒãã®ç¹æ®å
XãèšåãããŠããå Žåããã®ç¹æ®åã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯å€éšãã³ãã¬ãŒãã®å¯Ÿå¿ãããã€ã³ãã«äŸåããŸãã
- Xãé¢æ°ãã³ãã¬ãŒãã®ç¹æ®åã§ããå Žåãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãYãšäžèŽããŸãã
- Xãã¯ã©ã¹ãã³ãã¬ãŒãã®ç¹æ®åã§ããå Žåãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãYã®çŽåã«ãªããŸãã
ãã¹ãããããã³ãã¬ãŒãããªãå ŽåããŸãã¯ã³ã³ããã¹ããå€éšãã³ãã¬ãŒãã®ãã©ã¡ãŒã¿ãŒã«äŸåããªãå Žåãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯ãç¹æ®å
Xãèšåããããæãã°ããŒãã«ãªããšã³ãã£ãã£
ã®å®£èš/å®çŸ©ã®ãã€ã³ã
Dã«é¢é£ä»ããããŸãã
- Xãé¢æ°ãã³ãã¬ãŒãã®ç¹æ®åã§ããå Žåãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯Dã®çŽåŸã«ãªããŸãã
- Xãã¯ã©ã¹ãã³ãã¬ãŒãã®ç¹æ®åã§ããå Žåãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯Dã®çŽåã«ãªããŸãã
é¢æ°ãã³ãã¬ãŒãç¹åçæ
é¢æ°ãã³ãã¬ãŒãã®ç¹æ®åã«ã¯ãä»»æã®æ°ã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ããå«ããããšãã§ããŸãããã³ã³ãã€ã©ãŒãã©ã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ããéžæããŠã³ãŒããçæããŠãããã³ãã¬ãŒãå
ã®åŒã¯åãæå³ãæã€å¿
èŠããããŸãïŒããã§ãªãå Žåãããã°ã©ã ã¯æ£ãããªããšèŠãªãããŸãïŒ
ç°¡åã«ããããã«ãC ++æšæºã§ã¯ãã€ã³ã¹ã¿ã³ã¹åãããé¢æ°ãã³ãã¬ãŒãã®ç¹æ®åã«ã¯ã
翻蚳åäœã®æåŸã«è¿œå ã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ããããããšãèŠå®ããŠããŸãã
åå空é N
{
struct X { / *ç¹å¥ã«ç©ºçœã®ãŸãŸ* / } ã
void func ïŒ X ã int ïŒ ;
}
ãã³ãã¬ãŒã < typename T >
void call_func ïŒ T val ïŒ
{
func ïŒ val ã 3.14f ïŒ ;
}
int main ïŒ ïŒ
{
call_func ïŒ N :: X { } ïŒ ;
}
//æåã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ã
åå空é N
{
float func ïŒ X ã float ïŒ ;
}
// 2çªç®ã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ã
ãã®äŸã§ã¯ãé¢æ°
void call_func <N :: X>ïŒN :: XïŒã®ã€ã³ã¹ã¿ã³ã¹åã®2ã€ã®ãã€ã³ãããããŸãã æåã¯
mainã®å®çŸ©ã®çŽåŸïŒ
call_funcã¯ãã®å
éšã§åŒã³åºãããããïŒã§ã2çªç®ã¯ãã¡ã€ã«ã®æåŸã§ãã
call_func <N :: X>ã®åäœã¯ãç¹æ®åã³ãŒããçæããã³ã³ãã€ã©ãŒã«å¿ããŠå€åããããããã®äŸã¯æ£ãããããŸããã
- æåã®æç¹ã§ã call_funcã¯funcïŒXãintïŒãåŒã³åºããŸããããã¯ããã®æç¹ã§ã¯ä»ã®ãªãŒããŒããŒãããªãããã§ãã
- 2çªç®ã®æç¹ã§ã call_funcã¯ããã®æç¹ã§ãã§ã«å®£èšãããŠããfuncïŒXãfloatïŒããå©çšå¯èœãªãã¹ãŠã®ãªãŒããŒããŒãã®äžã§æãé©åãªãã®ãšããŠåŒã³åºããŸãã
ã¯ã©ã¹ãã³ãã¬ãŒãå°éåã®çæ
ã¯ã©ã¹ãã³ãã¬ãŒããç¹åããããã«ãæåã®ãã®ãé€ããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã¯ç¡èŠãããŸãã ããã¯ãå®éã«ã¯ãã€ã³ã¹ã¿ã³ã¹åãå¿
èŠãªã³ã³ããã¹ãã§ã³ã³ãã€ã©ãæåã«èšåããããšãã«ãã³ã³ãã€ã©ãç¹æ®åã³ãŒããçæããå¿
èŠãããããšãæå³ããŸãã
åå空é N
{
struct X { / *ç¹å¥ã«ç©ºçœã®ãŸãŸ* / } ã
void func ïŒ X ã int ïŒ ;
}
template < typename T > struct A { using type = decltype ïŒ func ïŒ T { } ã 3.14f ïŒ ïŒ ; } ;
template < typename T > struct B { type = decltype ïŒ func ïŒ T { } ã 3.14f ïŒ ïŒã䜿çšã㊠; } ;
//ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãA
int main ïŒ ïŒ
{
A < N :: X > a ;
}
åå空é N
{
float func ïŒ X ã float ïŒ ;
}
//ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãB
ãã€ã g ïŒ ïŒ
{
A < N :: X > :: ã¿ã€ã a ; //ééã£ãŠããŸããã¿ã€ã㯠`void`ã«ãªããŸã
B < N :: X > :: ã¿ã€ã b ; // OKãã¿ã€ãã¯ãfloatãã«ãªããŸã
}
ããã§ã¯ãã€ã³ã¹ã¿ã³ã¹åãã€ã³ã
A <N :: X>ã¯
mainã®çŽåã«ãªããã€ã³ã¹ã¿ã³ã¹åãã€ã³ã
B <N :: X>㯠gã®çŽåã«
ãªããŸãã
ãã¹ãŠããŸãšãã
ã¯ã©ã¹ãã³ãã¬ãŒãå
ã®
ãã¬ã³ã宣èšã«é¢é£ä»ããããã«ãŒã«ã¯ã次ã®å®çŸ©äŸã§ã¯
funcïŒshortïŒãš
funcïŒfloatïŒãçæãã
ãããããç¹æ®å
A <short>ãš
A <float>ã®ã€ã³ã¹ã¿ã³ã¹åãã€ã³ãã«é
眮ãããããšã瀺ããŠããŸãã
constexpr int func ïŒ short ïŒ ;
constexpr int func ïŒ float ïŒ ;
ãã³ãã¬ãŒã < typename T >
æ§é äœ A
{
åé constexpr int func ïŒ T ïŒ { 0ã è¿ã ; }
} ;
ãã³ãã¬ãŒã < typename T >
A < T >ã€ã³ãã€ã¬ã¯ã·ã§ã³ïŒ ïŒ
{
return { } ;
}
//ïŒ1ïŒ
int main ïŒ ïŒ
{
ã€ã³ãã€ã¬ã¯ã·ã§ã³< short > ïŒ ïŒ ; //ïŒ2ïŒ
ã€ã³ãã€ã¬ã¯ã·ã§ã³< float > ïŒ ïŒ ; //ïŒ3ïŒ
}
èšç®åŒã«é¢æ°ãã³ãã¬ãŒãã®ç¹æ®åã®åŒã³åºããå«ãŸããå Žåããã®ç¹æ®åã®æ»ãå€ã®åãå®å
šã«å®çŸ©ããå¿
èŠããããŸãã ãããã£ãŠãè¡ïŒ2ïŒããã³ïŒ3ïŒã®åŒã³åºãã¯ãã€ã³ã¹ã¿ã³ã¹åãã€ã³ãïŒé çªã«
mainã®åïŒã®åã«ã
éæ¥åç¹æ®åãšãšãã«ç¹æ®å
Aã®æé»çãªã€ã³ã¹ã¿ã³ã¹åãå¿
èŠãšããŸãã
è¡ïŒ2ïŒããã³ïŒ3ïŒã«å°éããåã«ãé¢æ°
funcïŒshortïŒããã³
funcïŒfloatïŒã å®£èš ãããŠãããã
å®çŸ©ãããŠããªãããšãéèŠã§ãã ãããã®è¡ã®éæã«ãããç¹æ®å
Aã®ã€ã³ã¹ã¿ã³ã¹åãçºçããå Žåããããã®é¢æ°ã®å®çŸ©ã¯è¡šç€ºãããŸããããããã®è¡ã®é£ã§ã¯ãªãããã€ã³ãïŒ1ïŒã«é
眮ãããŸãã
解決ç
äºåçãªæ
å ±ãããã®ã»ã¯ã·ã§ã³ã§èª¬æãããœãªã¥ãŒã·ã§ã³ã§äœ¿çšãããèšèªã®ãã¹ãŠã®åŽé¢ãååã«æããã«ããããšãé¡ã£ãŠããŸãã
念ã®ããã«ããœãªã¥ãŒã·ã§ã³ãã©ã®ããã«ããªãæ©èœããããå®å
šã«ç解ããããã«ã次ã®åŽé¢ã«ã€ããŠã®ã¢ã€ãã¢ãå¿
èŠã§ããããšãæãåºãããŠãã ããã
- ããŒã¯ãŒãfriend ãããã³;
- å®æ°åŒã®èŠåãããã³
- ãã³ãã¬ãŒãã®ã€ã³ã¹ã¿ã³ã¹åã®ã»ãã³ãã£ã¯ã¹ã
å®è£
constexpr int flag ïŒ int ïŒ ;
ãã³ãã¬ãŒã < typenameã¿ã°>
æ§é ã©ã€ã¿ãŒ
{
åé constexpr intãã©ã°ïŒã¿ã°ïŒ
{
0ã è¿ã ãŸã ã
}
} ;
ãã³ãã¬ãŒã < bool B ã typename Tag = int >
struct dependent_writer ïŒ writer <ã¿ã°> { } ;
ãã³ãã¬ãŒã <
bool B = noexcept ïŒ flag ïŒ 0 ïŒ ïŒ ã
int = sizeof ïŒ dependent_writer < B > ïŒ
>
constexpr int f ïŒ ïŒ
{
ãªã¿ãŒã³ B ;
}
int main ïŒ ïŒ
{
constexpr int a = f ïŒ ïŒ ;
constexpr int b = f ïŒ ïŒ ;
static_assert ïŒ a ïŒ= b ã "fail" ïŒ ;
}
æ³šïŒ clangã¯ãã®ã³ãŒãã§äžæ£ãªåäœã瀺ããŸã ãåé¿çã¯ã¢ããªã±ãŒã·ã§ã³ã§å©çšã§ããŸã ã
ã泚æ transïŒ Visual Studio 2015ã®èŠèŠçãªãã¥ãŒã¯ã fïŒïŒã®å€æŽã«ããæ°ä»ããªããã ãã ããã³ã³ãã€ã«åŸã aãšbã®å€ã¯ç°ãªããŸãã
ããããããã¯ã©ã®ããã«æ©èœããŸããïŒ
äºåæ
å ±ãèªãã å Žåãäžèšã®è§£æ±ºçãç解ããããšã§åé¡ãçããããšã¯ãããŸãããããã®å Žåã§ããããŸããŸãªéšåã®åäœåçã®è©³çŽ°ãªèª¬æãèå³æ·±ãå ŽåããããŸãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ããœãŒã¹ã³ãŒããã¹ãããããšã«åæããåãã©ã°ã¡ã³ãã«ã€ããŠç°¡åãªèª¬æãšæ£åœæ§ã瀺ããŸãã
ãå€æ°ã
ããã°ã©ã ã®åãã€ã³ãã§ã
constexpré¢æ°ã¯2ã€ã®ç¶æ
ã®ããããã«ãªããŸããæ¢ã«å®çŸ©ãããŠãããå®æ°åŒããåŒã³åºãããšãã§ãããã©ããã§ãã ããã2ã€ã®ç¶æ³ã®ããããã®ã¿ãå¯èœã§ãïŒãããŸããªåäœãèš±å¯ããªãéãïŒã
éåžžã
constexpré¢æ°ã¯é¢æ°ãšèŠãªãããæ£ç¢ºã«äœ¿çšãããŸãããäžèšã®ãããã§ã
boolã«äŒŒãåãæã€ãå€æ°ããšèããããšãã§ããŸãã ãã®ãããªåãå€æ°ãã¯ããå®çŸ©æžã¿ããŸãã¯ãæªå®çŸ©ãã®2ã€ã®ç¶æ
ã®ããããã§ãã
constexpr int flag ïŒ int ïŒ ;
ãã®ããã°ã©ã ã§ã¯ã
ãã©ã°é¢æ°ã¯åæ§ã®ããªã¬ãŒã§ãã ã©ãã§ãé¢æ°ãšããŠåŒã³åºãã®ã§ã¯ãªãããå€æ°ããšããŠã®çŸåšã®ç¶æ
ã«ã®ã¿é¢å¿ããããŸãã
修食å
writerã¯ãã€ã³ã¹ã¿ã³ã¹åããããšããã®åå空éïŒãã®å Žåã¯ã°ããŒãã«ïŒã§é¢æ°ã®å®çŸ©ãäœæããã¯ã©ã¹ãã³ãã¬ãŒãã§ãã
ã¿ã°ãã³ãã¬ãŒããã©ã¡ãŒã¿ã¯ãå®çŸ©ãäœæãããé¢æ°ã®ç¹å®ã®ã·ã°ããã£ãå®çŸ©ããŸãã
ãã³ãã¬ãŒã < typenameã¿ã°>
æ§é ã©ã€ã¿ãŒ
{
åé constexpr intãã©ã°ïŒã¿ã°ïŒ
{
0ã è¿ã ãŸã ã
}
} ;
äºå®éãã
constexpr -functionsããå€æ°ããšèŠãªãå Žåããã³ãã¬ãŒãåŒæ°
Tã䜿çšã
㊠ã©ã€ã¿ãŒãäœæãããšããå€æ°ãã®ã·ã°ããã£
int funcïŒTïŒããå®çŸ©æžã¿ãäœçœ®ã«ç¡æ¡ä»¶ã«å€æãããŸãã
ãããã·
ãã³ãã¬ãŒã < bool B ã typename Tag = int >
struct dependent_writer ïŒ writer <ã¿ã°> { } ;
dependent_writerãã€ã³ãã€ã¬ã¯ã·ã§ã³ãè¿œå ããç¡æå³ãªã¬ã€ã€ãŒã®ããã«èŠãããšæ±ºããŠãé©ãããšã§ã¯ãããŸããã
dependent_writerãä»ããŠã¢ã¯ã»ã¹ããã®ã§ã¯ãªãããå€æ°ãã®å€ãå€æŽãã
ã©ã€ã¿ãŒ<Tag>ãçŽæ¥ã€ã³ã¹ã¿ã³ã¹åããªãã®ã¯ãªãã§ããïŒ
äºå®ã
ã©ã€ã¿ãŒ<int>ãžã®çŽæ¥åŒã³åºãã¯ãé¢æ°ãã³ãã¬ãŒã
fã®æåã®åŒæ°ã2çªç®ãããæ©ãè©äŸ¡ãããããšãä¿èšŒããŸããïŒãããŠãé¢æ°ã¯ãæåã®åŒã³åºãã§
falseãè¿ãå¿
èŠãããããšããèšæ¶ããããã®åŸã§ãå€æ°ãã®å€ãå€æŽããã ãã§ãïŒ ã
å¿
èŠãªãã³ãã¬ãŒãåŒæ°ãèšç®ããé åºãèšå®ããã«ã¯ãdependent_writerã䜿çšããŠè¿œå ã®äŸåé¢ä¿ãè¿œå ã§ããŸãã æåã®
dependent_writerãã³ãã¬ãŒãåŒæ°ã¯ãã€ã³ã¹ã¿ã³ã¹åãããåã«è©äŸ¡ãããå¿
èŠãããããã
ã©ã€ã¿ãŒãã€ã³ã¹ã¿ã³ã¹åãããåã«è©äŸ¡ããå¿
èŠã
ãããŸãã ãããã£ãŠã
Bã
dependent_writerã«åŒæ°ãšããŠæž¡ããšã
ã©ã€ã¿ãŒãã€ã³ã¹ã¿ã³ã¹åããããŸã§ã«ã
fã«ãã£ãŠè¿ãããå€ããã§ã«èšç®ãããŠããããšã確èªã§ããŸãã
泚ïŒå®è£
ãäœæããéã«ãå€ãã®ä»£æ¿æ¡ãæ€èšããæãç°¡åã«ç解ã§ãããã®ãèŠã€ããããšããŸããã ãã®æçãããŸãã«ãæ··ä¹±ããªãããšãå¿ããé¡ã£ãŠããŸãã
éæ³
ãã³ãã¬ãŒã <
bool B = noexcept ïŒ flag ïŒ 0 ïŒ ïŒ ã //ïŒ1ïŒ
int = sizeof ïŒ dependent_writer < B > ïŒ //ïŒ2ïŒ
>
constexpr int f ïŒ ïŒ
{
ãªã¿ãŒã³ B ;
}
ãã®ã¹ããããã¯å°ãå¥åŠã«èŠãããããããŸããããå®éã«ã¯éåžžã«ç°¡åã§ãïŒ
- ïŒ1ïŒ ãã©ã°ïŒ0ïŒãå®æ°åŒã®å Žåã¯Bãtrueã«èšå®ããããã§ãªãå Žåã¯falseã«èšå®ããŸãã
- ïŒ2ïŒ dependent_writer <B>ãæé»çã«ã€ã³ã¹ã¿ã³ã¹åããŸãïŒ sizeofæŒç®åã«ã¯å®å
šã«å®çŸ©ãããåãå¿
èŠã§ãïŒã åæã«ã ã©ã€ã¿ãŒ<B>ãã€ã³ã¹ã¿ã³ã¹åãããŸããããã«ããã intãã©ã°ïŒintïŒã®å®çŸ©ãå®çŸ©ããããå€æ°ãã®ç¶æ
ãå€æŽãããŸãã
åäœã¯ã次ã®æ¬äŒŒã³ãŒãã§è¡šçŸã§ããŸãã
[ `int flag (int)` ]: `B` = `false` `dependent_writer <false>` `B` : `B` = `true` `dependent_writer <true>` `B`
ãããã£ãŠãæåã«
fãåŒã³åºããããšããã³ãã¬ãŒãåŒæ°
Bã¯
falseã«ãªã
ãŸããã
fãåŒã³åºãå¯äœçšã¯ãå€æ°ã
ãã©ã°ã®ç¶æ
ã®å€åã«ãªããŸãïŒãã®å®çŸ©ãçæããŠbody
mainã®åã«é
眮ããŸãïŒã ããã«
fãåŒã³åºããš
ã ãå€æ°ã
ãã©ã°ã¯ãã§ã«ãå®çŸ©æžã¿ãç¶æ
ã«ãªã£ãŠããããã
Bã¯
trueã«ãªã
ãŸã ã
ãããã«
C ++ïŒä»¥åã¯äžå¯èœãšèããããŠããïŒã§æ°ããããšãè¡ãããã®ã¯ã¬ã€ãžãŒãªæ¹æ³ã人ã
ãçºèŠãç¶ããŠãããšããäºå®ã¯ãé©ãã¹ããã®ã§ãããã²ã©ããã®ã§ãã - ã¢ãŒãªã¹ã»ãã¹
ãã®èšäºã§ã¯ãå®æ°åŒã«ç¶æ
ãè¿œå ããåºæ¬çãªèãæ¹ã«ã€ããŠèª¬æããŸãã èšãæããã°ãå®æ°è¡šçŸã¯ãå®æ°ãã§ãããšããäžè¬ã«åãå
¥ããããŠããçè«ïŒç§ãããåç
§ããïŒã¯ãä»ã§ã¯ç Žå£ãããŠããŸãã
ã泚æ transïŒç§ã®æèŠã§ã¯ããç Žå£ãããããšããèšèã¯éåžžã«åŒ·åã§ãã åãããã«ãååã®åäžæ§ã«ããããããããã³ãã¬ãŒãé¢æ°fïŒïŒã® 2ã€ã®ç°ãªãç¹æ®åããœãªã¥ãŒã·ã§ã³ã§åŒã³åºããããããããå®å
šã«ãäžå®ãã§ãã ãã¡ãããããã¯ã¢ã€ãã¢ã®äžè¬çãªæçšæ§ãæãªããã®ã§ã¯ãããŸããã
ãã®èšäºãæžããŠãããšã
ããã³ãã¬ãŒãã¡ã¿ããã°ã©ãã³ã°ã®
æŽå²ãšããã®èšèªã䜿çšãããšãæå³ãã以äžã®ããšãã§ããããã«ãªãã®ãã©ãã»ã©å¥åŠã
ãèããã«
ã¯ããããŸããã§ããã
次ã¯ïŒ
smetaãšåŒã°ãã
åœä»€åãã³ãã¬ãŒãã¡ã¿ããã°ã©ãã³ã°çšã®ã©ã€ãã©ãªã
äœæã ãŸãã ãããã¯ãä»åŸã®èšäºã§å
¬éã説æãããã³è°è«ãããŸãã åãäžãããããã¯ã®äžã§ïŒ
- ã³ã³ãã€ã«æã«ãŠã³ã¿ãŒãå®è£
ããæ¹æ³
- ã³ã³ãã€ã«æã¡ã¿ã¿ã€ãã³ã³ãããŒãå®è£
ããæ¹æ³
- 茻茳蚱å¯ã確èªããã³ç®¡çããæ¹æ³
- C ++ã§ãªãã¬ã¯ã·ã§ã³ãè¿œå ããæ¹æ³
ã泚æ transïŒèè
ã¯ã smetaã®ãªãªãŒã¹ããã£ã³ã»ã«ããããšã決ãããšå ±åããŠããŸãã ãã®èšäºããã³åŸç¶ã®èšäºã«ã¯ããã®æ©èœã®ã»ãšãã©ãã¹ãŠãå«ãŸããŠããïŒãŸãã¯å«ãŸããïŒãããèªè
ãç¬èªã«æ©èœãå®è£
ããããšèªäœã¯ãããããªããšã§ãã ããšãã°ãç§ã¯ãã§ã«ïŒPhilipã®èŠåã«åããŠïŒããã€ãã®ã¢ã€ãã¢ã玹ä»ããŠãããå°æ¥ããããã©ã€ãã©ãªã®ãããªãã®ã«éããã€ããã§ãã
ã¢ããª
clangã®
ãã® ïŒããã³é¢é£ããïŒãã°ã®ãããäžèšã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãæ£ããå®è£
ãããŠããå Žåãããã°ã©ã ãæ£ããåäœããŸããã 以äžã¯ã
clangåãã«ç¹å¥ã«äœæããããœãªã¥ãŒã·ã§ã³ã®ä»£æ¿å®è£
ã§ãïŒããã¯ãŸã æå¹ãªC ++ã³ãŒãã§ãããã©ã®ã³ã³ãã€ã©ã§ã䜿çšã§ããŸãããå€å°è€éã§ãïŒã
åå空éã®è©³çŽ°
{
æ§é äœ A
{
constexpr A ïŒ ïŒ { }
åé constexpr int adl_flag ïŒ A ïŒ ;
} ;
ãã³ãã¬ãŒã < typenameã¿ã°>
æ§é ã©ã€ã¿ãŒ
{
friend constexpr int adl_flag ïŒã¿ã°ïŒ
{
0ã è¿ã ãŸã ã
}
} ;
}
template < typename Tag ã int = adl_flag ïŒ Tag { } ïŒ >
constexpr bool is_flag_usable ïŒ int ïŒ
{
trueãè¿ããŸãã
}
ãã³ãã¬ãŒã < typenameã¿ã°>
constexpr bool is_flag_usable ïŒ ... ïŒ
{
falseãè¿ããŸãã
}
ãã³ãã¬ãŒã < bool B ã ã¯ã©ã¹ Tag = detail :: A >
struct dependent_writer ïŒ detail :: writer <ã¿ã°> { } ;
ãã³ãã¬ãŒã <
class Tag = detail :: A ã
bool B = is_flag_usable <ã¿ã°> ïŒ 0 ïŒ ã
int = sizeof ïŒ dependent_writer < B > ïŒ
>
constexpr int f ïŒ ïŒ
{
ãªã¿ãŒã³ B ;
}
int main ïŒ ïŒ
{
constexpr int a = f ïŒ ïŒ ;
constexpr int b = f ïŒ ïŒ ;
static_assert ïŒ a ïŒ= b ã "fail" ïŒ ;
}
泚ïŒçŸåšããã®åé¿çãclangã§å¹ççã§ããçç±ã瀺ã察å¿ãããã°ã¬ããŒããæžããŠããŸãã ããããžã®ãªã³ã¯ã¯ãã¬ããŒããæåºããããšããã«è¿œå ãããŸãïŒãã¹ãŠãéãé- çŽPerã ïŒã
å
ã®èšäºã®æè¬ã»ã¯ã·ã§ã³è¬èŸ
ãã®èšäºãæžããªã人ã¯ããããããŸãããç¹ã«æè¬ããŠããŸãã
- ã¢ãŒãªã¹ã»ãã¹
- ã¢ã€ãã¢ã®çå®ãæ¯æŽããŸãã
- ã³ã³ã¿ã¯ãã¬ã³ãºã賌å
¥ããããã®è³éãæäŸããŠãããã®ã§ãç²ç®çã«æžãå¿
èŠããªããªããŸããã
- èšäºã«å¯Ÿãã圌ã®æèŠã«å¯Ÿããç§ã®å«ãããã®èš±å®¹ã
- ãã€ã±ã«ã»ãã«ãã©ã€ãã³
- 蚌æ ãããã³ãã®èšäºãããç解ããããããæ¹æ³ã«é¢ããèå³æ·±ãèãã
- ã³ãã³ã
- 説æããææ³ãäžæ£ãªããã°ã©ã ãçæããããšã蚌æããããšããŠå€±æããïŒç§ã®é¡ã«C ++æšæºã®æ®µèœãæããŠïŒã ã©ã¡ãããšããã°ãç§ã¯åœŒã®ããã«åãããšãããŸãã
翻蚳è
ãã
ç§ã¯ãã®èšäºã«çŽ1ãæåã«åºãããããã³ãã¬ãŒãã®ã¡ã¿ããã°ã©ãã³ã°ã«æ©èœæ§ãã°ããŒãã«ç¶æ
ãžã®äŸåæ§ãè¿œå ã§ããã¢ã€ãã¢
ã®æµã¿ã®
ã²ã©ããããã€ãã«æéãåããŸããã ãã®èšäºã®èè
ã
Philippe Rosenã¯ãéçºè
ããã¥ãŒãžã·ã£ã³ããã¡ãã·ã§ã³ã¢ãã«ã§ãããè¯ã人ã§ãããã芪åã«ãã·ã¢èªã«ç¿»èš³ããããšãèš±å¯ããŠãããŸããã
ãã®èšäºã¯ãåœä»€åã¡ã¿ããã°ã©ãã³ã°
ã«é¢ããäžé£ã®èšäºã®æåã®èšäºã§ãããå®éã®ã¡ã¿ããã°ã©ãã³ã°ãã¯ããã«äŸ¿å©ã«ããæ§æãå®è£
ããåã«ãéå®æ°
constexprs ïŒå®éã®å³æé©çšæ§ã¯éåžžã«éãããŠããŸãïŒã®ã¢ã€ãã¢ãéçºããŸãã
è¿ãå°æ¥ãæ®ãã®2ã€ã®èšäºïŒã³ã³ãã€ã«æã«ãŠã³ã¿ãŒãšã¡ã¿ã¿ã€ãã®ã³ã³ãããŒã«ã€ããŠïŒã翻蚳ããŸãã ããã«ããã£ãªããã¯ãè¿ãå°æ¥ãã·ãªãŒãºãç¶ç¶ããããã«ã¢ã€ãã¢ãçºå±ããããšè¿°ã¹ãŸããïŒãã¡ãããæ°ãã翻蚳ããããŸãïŒã
èšæ£ãè¿œå ãåžæã¯å€§æè¿ã§ãã ãã£ãªããèªèº«ã«
æçŽã
æžãããšãã§ããŸãã圌ã¯ã©ããªã³ã¡ã³ãã§ãåãã§ããããšæããŸãã