ã¯ããã«
id:kazuhooku ããã
Kazuho@Cybozu Labs: なんとなくリフレクション in C++
ã¨ããè¨äºãæ¸ãã¦ãã¦ããªããåããï¼
ããããï¼
ã§ããèªãã¾ããï¼ï¼ Template æãï¼ï¼
ã¨ãã訳ã§
C++ Template ã®åå¼·ããã¦ã¿ããï¼
ãããã°ãã¡ãã£ã¨åã« 1000speakers ã§ä¸éæ°ã« C++ Template ã¯ãã¥ã¼ãªã³ã°å®å
¨ãé¢æ°åè¨èªã¨ãããããªãã¨ãèããããããï¼
ããããããããªãã¨ãåºæ¥ãã¯ãï¼
ã¨ãã訳ã§
JavaScript ã§åºæ¥ããã¨ã C++ ã§åºæ¥ããã試ãã¦ã¿ããï¼
ã¾ã
é¢æ°ãã³ãã¬ã¼ãã¨æ§é ä½ãã³ãã¬ã¼ãã©ã£ã¡ã§ JavaScript ã®é¢æ°ã表ç¾ããã¹ãããèããã
C++ ã®ææ³ãèãã
// ããã¯ã§ããªãï¼ï¼ void foo() { void bar() { void baz() { } } }
// ããã¯ã§ããï¼ struct foo { struct bar { struct baz { } } }
C++ ã®é¢æ°ã¯ãã¹ãåºæ¥ãªããã§ãæ§é ä½ã¯ãã¹ãåºæ¥ãï¼
ã¨ãã訳ã§ãæ§é ä½ãã³ãã¬ã¼ã㧠JavaScript ã®é¢æ°ã«åºæ¥ããã¨ãããããã©ããããã£ã¦ã¿ãã
æ§é ä½ = Activation ãªãã¸ã§ã¯ã
æ§é ä½ã®ã¡ã³ãã®ã¹ã³ã¼ããèãã
struct hoge { int fuga; // ãã® fuga ã¯ãããã ï¼ ï¼ // ãã®ä¸æ¬å¼§ã®çµããã¾ã§æå¹ };
ãã¹ããã¦æ§é ä½ã®ã¡ã³ãã®ã¹ã³ã¼ããèãã
struct puga { struct hoge { typedef int fuga; // ãã® fuga ã¯ãããã ï¼ ï¼ // ãã®ä¸æ¬å¼§ã®çµããã¾ã§æå¹ }; struct piyo { typedef int fuga; // ãã® fuga ã¯ãããã ï¼ ï¼ // ãã®ä¸æ¬å¼§ã®çµããã¾ã§æå¹ }; };
ã¨ããããã§ã struct å
ã§å®£è¨ãããã¡ã³ãå¤æ°åãã¡ã³ãå(?)åãã¡ã³ãæ§é ä½(?)å㯠struct å
ã®ã¬ãã·ã«ã«ã¹ã³ã¼ãã§æå¹ã§ããã
JavaScript ã® Activation ãªãã¸ã§ã¯ãã¯é¢æ°ãè©ä¾¡ããããã¨ã«ä¸ã¤ä½ããããã®ããããã£åã¯é¢æ°å
ã®ã¬ãã·ã«ã«ã¹ã³ã¼ãã®ä¸ã§å¤æ°ã¨ãã¦ä½¿ããã
æ§é ä½ãæ§é ä½ãã³ãã¬ã¼ããå®ä½åï¼ã¨ããè¨èã§ããã®ããªï¼ããããã¨ã«ä¸ã¤ä½ããããã®ã¡ã³ãåã¯æ§é ä½å
ã®ã¬ãã·ã«ã«ã¹ã³ã¼ãã®ä¸ã§ä½¿ããã
ã¤ã¾ãã以ä¸ã®ããã«å¯¾å¿ãã¦ãã
JavaScript | C++ Template |
---|---|
å¤ | å®æ°ãå |
é¢æ° | æ§é ä½ãã³ãã¬ã¼ã |
Activationãªãã¸ã§ã¯ã | æ§é ä½ |
å¤æ°åï¼Activation ãªãã¸ã§ã¯ãã®ããããã£åï¼ | ã¡ã³ãå |
å¤æ°ã¸ã®ä»£å ¥ | ã¡ã³ãååã«åã typedefãã¡ã³ãå¤æ°ã«å®æ°ãä»£å ¥ |
return ã§å¤ãè¿ã | :: ã§ãå¼ã³åºããå´ããå¤ãåã |
è¿ãå¤ã«é¢ãã¦ã¯ãå°ãããªããã¼ã§ããã
JavaScript ã§ã¯ãå¼ã³åºãããå´ãè¿ãå¤ã決ããã®ã§ããã C++ ã§ã¯å¼ã³åºããï¼å®ä½åããå´ã Hoge
// JS function hoge(x) { return x; } var a = hoge(x);
// C++ template <typename x> struct hoge { typedef x v; // è¿ãå¤ãé©å½ãªå¤æ°ï¼ã¡ã³ãåï¼ã«ä»£å ¥ï¼typedefï¼ãã¦ãã }; typedef hoge<x>::v a; // hoge ãå¼ã³åºãã¦è¿ãå¤ããã¡ãããæå®ãã
ãã³ãã¬ã¼ã㯠C++ Template ã«ãããã第ä¸ç´ã®ãªãã¸ã§ã¯ãã§ã¯ãªã
第ä¸ç´ã®ãªãã¸ã§ã¯ãã¨ã¯ãå¤æ°ã¨ãã¦ååãã¤ãããã¦ãæç¶ãã«å¼æ°ã¨ãã¦æ¸¡ãã¦ãçµæã¨ãã¦è¿ããå¤ã®ãã¨ã
以ä¸ã®ã¨ã³ããªã詳ããã
http://d.hatena.ne.jp/heppokoprogram/20060201#1138803596
ãã³ãã¬ã¼ãï¼JavaScript ã§ããé¢æ°ï¼ã第ä¸ç´ã®ãªãã¸ã§ã¯ããããªãã®ã§ã JavaScript ã§ã®ä»¥ä¸ã®ãããªãã¨ãã§ããªãã
// JS function hoge(f, x) { // å¼æ°ã«é¢æ°ãåãåã return f(x); // åãåã£ãé¢æ°ãå¼ã³åºã }
// C++ // ãã³ãã¬ã¼ã hoge template <typename f, int x> struct hoge { // å¼æ°ã«ãã³ãã¬ã¼ããåãåããªã // static const int v = f<x>::v; // f ã¯ãã³ãã¬ã¼ãã¯ããããªãã®ã§ã¨ã©ã¼ã«ãªã£ã¡ããï¼ï¼ };
ãã³ãã¬ã¼ããæ§é ä½ã§å²ãã°ãã
å㯠C++ Template ã«ããã第ä¸ç´ã®ãªãã¸ã§ã¯ããªã®ã§å¼æ°ã«æ¸¡ããããªã®ã§ãã¡ã³ãã«ãã³ãã¬ã¼ããä¸åã ããã£ãæ§é ä½ãä½ãã°ããã
ã¤ã¡ã¼ã¸ã¨ãã¦ã¯ã Java ã§ãã¾ã«è¦ããããã¤ãã¡ã½ãããä¸åã ãæã£ãã¯ã©ã¹ãä½ãã°ããã
// ãã³ãã¬ã¼ã hoge template <typename f, int x> struct hoge { // å¼æ°ã«ãã³ãã¬ã¼ããåãåããªã static const int v = f::template _<x>::v; // å¼ã³åºããï¼ï¼ }; // fuga ã¯åï¼ç¬¬ä¸ç´ã®ãªãã¸ã§ã¯ãï¼ struct fuga { template <int a> struct _ { static const int v = a; }; }; static const int a = hoge<fuga, 10>::v; #include <iostream> using namespace std; int main() { cout << a << endl; } // 10
JavaScript 㨠C++ Template ã®å½¢å¼çãªæ¸ãæã
ãã¨ãã°ã C++ Template ã§ã¯ä»¥ä¸ã®ãããªéãããã
- ãã³ãã¬ã¼ããå ä¸ç´ã®ãªãã¸ã§ã¯ããããªãï¼ãã£ãè¿°ã¹ãï¼
- å¼æ°ã«åããã
- return ããªããã©ãå¼ã³åºãå´ããã¹ã³ã¼ãã«ã¢ã¯ã»ã¹ã§ããã
ãªã®ã§
- JavaScript ã®é¢æ°ã¯ãæ§é ä½ã§å²ãã ãã³ãã¬ã¼ãã«å¤æ
- æ°å¤åããã¹ã¦æ§é ä½ã§å²ãã§ãå¼æ°ã®åããã¹ã¦ typename ã«ãã
- return hoge; 㯠typdef hoge v; ã«å¤æãã
- é¢æ°å¼ã³åºãã¯ããã³ãã¬ã¼ãã®å®ä½å㨠::v ã«å¤æãã
ããããã«ã¼ã«ã§æ¸ãæããã°ãå¼ãä¸ã¤ãããªãã¦æ´æ°ããæ±ããªããã㪠JavaScript ã®é¢æ°ãªã C++ Template ã®ãã³ãã¬ã¼ãã«æ¸ãæãããã¨ãã§ããããããªããã
ä¾
ä¾ã¨ã㦠JavaScript ã§æ¸ãããã£ã¼ãæ°ã C++ Template ã«ç´ãã¦ã¿ã¾ãã
ãã£ã¼ãæ°ã«ã¤ãã¦ã¯ã以ä¸ã詳ããã§ãã
ラムダ計算 - Wikipedia
zero (0)
function zero(f) { return function(x) { return x; } }
C++ Template
struct zero { template <typename f> struct _ { struct v { template <typename x> struct _ { typedef x v; }; }; }; };
succ (1 足ã)
function succ(n) { return function(f) { return function(x) { return f(n(f)(x)); } } }
C++ Template
struct succ { template <typename n> struct _ { struct v { template <typename f> struct _ { struct v { template <typename x> struct _ { typedef typename f::template _< typename n::template _< f >::v::template _< x >::v >::v v; }; }; }; }; }; };
plus (足ãç®)
function plus(m) { return function(n) { return function(f) { return function(x) { return m(f)(n(f)(x)); } } } }
C++ Template
struct plus_ { template <typename m> struct _ { struct v { template <typename n> struct _ { struct v { template <typename f> struct _ { struct v { template <typename x> struct _ { typedef typename m::template _<f>::v::template _< typename n::template _< f >::v::template _< x >::v >::v v; }; }; }; }; }; }; }; };
mult (ããç®)
function mult(m) { return function(n) { return function(f) { return m(n(f)) } } }
C++ Template
struct mult { template <typename m> struct _ { struct v { template <typename n> struct _ { struct v { template <typename f> struct _ { typedef typename m::template _< typename n::template _< f >::v >::v v; }; }; }; }; }; };
ã½ã¼ã¹å ¨ä½
#include <iostream> using namespace std; // ãã£ã¼ãæ°ã® 0 struct zero { template <typename f> struct _ { struct v { template <typename x> struct _ { typedef x v; }; }; }; }; // ãã£ã¼ãæ°ã« 1 ã足ã struct succ { template <typename n> struct _ { struct v { template <typename f> struct _ { struct v { template <typename x> struct _ { typedef typename f::template _< typename n::template _< f >::v::template _< x >::v >::v v; }; }; }; }; }; }; // ãã£ã¼ãæ°ã«ã©ããã®è¶³ãç® struct plus_ { template <typename m> struct _ { struct v { template <typename n> struct _ { struct v { template <typename f> struct _ { struct v { template <typename x> struct _ { typedef typename m::template _<f>::v::template _< typename n::template _< f >::v::template _< x >::v >::v v; }; }; }; }; }; }; }; }; // ãã£ã¼ãæ°ã«ã©ããã®ããç® struct mult { template <typename m> struct _ { struct v { template <typename n> struct _ { struct v { template <typename f> struct _ { typedef typename m::template _< typename n::template _< f >::v >::v v; }; }; }; }; }; }; // 1 ãã 10 ã¾ã§ã®ãã£ã¼ãæ°ãã¦ãã¨ã¼ã«ä½ã typedef succ::_<zero>::v one; // 0+1 typedef succ::_<one>::v two; // 1+1 typedef plus_::_<one>::v::_<two>::v three; // 1+2 typedef mult::_<two>::v::_<two>::v four; // 2*2 typedef plus_::_<two>::v::_<three>::v five; // 2+3 typedef mult::_<two>::v::_<three>::v six; // 2*3 typedef plus_::_<four>::v::_<three>::v seven; // 4+3 typedef mult::_<two>::v::_<four>::v eight; // 2*4 typedef mult::_<three>::v::_<three>::v nine; // 3*3 typedef succ::_<nine>::v ten; // 9+1 // ãã£ã¼ãæ°ãé C++ Template ã® C++ ã®ä¸çã®å®æ°ãã struct add_real_one { template <typename n> struct _ { struct v { static const int int_val = n::int_val + 1; }; }; }; struct real_zero { static const int int_val = 0; }; #define PUTS(n) cout << n::_<add_real_one>::v::_<real_zero>::v::int_val << endl // ã¡ã¤ã³ int main() { PUTS(zero); PUTS(one); PUTS(two); PUTS(three); PUTS(four); PUTS(five); PUTS(six); PUTS(seven); PUTS(eight); PUTS(nine); PUTS(ten); return 0; }
å®è¡ãã¦ã¿ã
$ g++ hoge.cpp && ./a.out 0 1 2 3 4 5 6 7 8 9 10 $
ãããããããï¼åãã¦ã¾ãï¼
C++ Template ãããï¼
æå¾ã«
ãããå¦ã¶éç¨ã§ãå
æããã奥ä¸ç©ããã沢山ã¢ããã¤ã¹ãããã¾ããï¼
ãããã¨ããããã¾ãï¼
æ¬å½ã¯ããã£ã¨ãã£ã±ãä¾ãæ¸ãããã£ãã®ã§ãããåã¤ãã¾ããï¼ï¼