1 名前:デフォルトの名無しさん [2008/02/16(土) 12:45:02 ] ・ここはC++のテンプレートメタプログラミング専用スレです。 ・なかったので立てました。 ・前にもあったような気がするけど気にしない。 ・次期C++(0x) boost STLの話題も、TMPに関係するならここにどうぞ。 仲良く使ってね。
48 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:31:58 ] コンパイル時間の節約は分かるんだが、 いざヘッダファイルをインクルードして何か使おうとすると 実装が無いとか文句言われることがあるのが困るんだよな。
49 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:32:21 ] 実装じゃねえや。定義だ。
50 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:33:06 ] >>48 ただの誤用にしか聞こえんのだが、どういう状況の話?
51 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:39:01 ] 不完全型のみで十分な状況では その型を定義してあるヘッダをインクルードせず、 不完全型の宣言のみを書く。 そして、その型を使ってるソースファイルでのみ、 そのヘッダファイルをインクルードする。
52 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:59:36 ] なんかC++の基本もまともに出来ないような人が居ますね。
53 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 02:18:38 ] TMPやるにはHaskell勉強した方が良いって本当ですか?
54 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 02:20:47 ] >>53 変数への代入ができないという制約の下でどうやって問題を解決するかを学ぶ、 という点で本当だと思う。
55 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 10:28:54 ] SICP読んだらModern C++ Designが分かった
56 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 13:01:03 ] Scheme勉強したらModern C++ Designが分かった
57 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 13:47:54 ] あれって別の関数型言語を勉強してからじゃないと理解できないほど難しいか?
58 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 13:59:44 ] ムチャクチャな書き方をしないといけないからわかりにくいんだよ。 すっきりした表記の関数型言語を勉強した後だと どういうトリックなのかがすんなり理解できる。
59 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 14:01:52 ] 別に無茶苦茶ではないと思うが。
60 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 14:54:27 ] 再帰に継承が絡んでくると難しく感じる。
61 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 14:56:58 ] 慣れてないだけだな。それにあんなもの別にC++以外のものを触ったって慣れやしない。
62 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 15:32:39 ] ところで>>2 のp_stabeには誰もつっこまないの? p_stadeじゃないかって
63 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 15:37:29 ] q_stabe
64 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 16:57:57 ] >>61 それは違うと思う。関数型言語のほうが記法が簡便だが抽象度が高く センスが必要。LispでもSchemeでも自在に扱えればC++のメタなんて少し の時間でマスターできる。templateなんて少しの時間でマスターできる。 経験上確信してる。逆は成立しない。
65 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 17:19:20 ] 千差万別、十人十色 自論に固執すること愚か也
66 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 17:32:39 ] 言語に組み込まれてるってのは重要だよな。 C++だとマクロとかでちょっと文法の解釈を脳内変換すれば いいんだけど手間が増大するのと 初学者に扱える代物ではなくなってしまうんだよね。
67 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 18:10:14 ] >>65 関数型言語の経験ないだろ?
68 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 18:10:49 ] >>65 SICPは読んだ?
69 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 18:25:10 ] 負けへん、負けへん 山ちゃんは負けへんでええ
70 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 18:25:39 ] 誰か質問しろよ。 スレ落ちるの時間の問題だな。
71 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 18:30:41 ] C++0xではmplは入らなくてTypeTraitsどまりってことは mplはまだ重視されてないってこと?メイヤーズの本では TMPがC++の中心に来ることはないなんて書いてあったけど どうなんだろ?
72 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 19:20:00 ] そうなんでしょう。 だって頭の体操にはなるけど、あんまり実用性ないじゃん。
73 名前:デフォルトの名無しさん [2008/02/18(月) 19:27:11 ] type_traitsはフレームワークであって、 みんなが自分のクラスのtraitsを提供しないと真価を発揮しないけど、 mplは使いたい人が使えばいいだけだから標準化しなくても困らない。
74 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 19:38:50 ] C++0x において提案されている <type_traits> で提供される機能の中には コンパイラが持っている独自の情報を吐いてくれないと実装できないものも多いので そういう意味で TypeTraits は優先的に規格として明示してくれないと困るかと
75 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 19:40:35 ] call_traits は追加されるの?
76 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 20:41:26 ] MP専用の構文を入れる気はもうないのかね Templateでできたのはたまたまであって、 いつまでもあんなハックみたいな書き方したくないなぁ
77 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 23:08:07 ] バッドノウハウ
78 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 02:44:27 ] 完全体のC++かどうかを判断するために compiler_traits が必要な気がする。
79 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 02:49:56 ] そうなるとまず has_compiler_traits が必要だな。
80 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 21:01:07 ] >>76 D言語の出番ですね、分かります
81 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 23:57:02 ] いやあ、すべってるねえ このスレ
82 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:07:56 ] 昔ProgramingJemsにメタプログラミングでsinテーブルを生成するっていうネタがあった 当時メタプログラミングなんて知らなくて、 「すげぇぇぇぇ」と感動して自分でも作ってみた しかし当時のオレのショボマシンではコンパイル時のサインテーブルの生成に結構な時間がかかり 最終的に、 Perlでテーブル書いたソースジェネレートした方が早くね? という結論に
83 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:13:14 ] メタプログラミングとは? テンプレート、型、typedef、コンパイル時定数、再帰を 駆使したコンパイル時プログラミングで合ってる?
84 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:15:48 ] テンプレートメタプログラミングならそれでまあ合ってる。
85 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:18:10 ] >>83 それはテンプレートメタプログラミングの説明だな メタプログラミング自体はもっと広く、プログラムを操作するプログラム全般をいう プリプロセッサを使うのもメタプログラミングだし、コードジェネレータを書くのも含む
86 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:20:22 ] テンプレート抜けてた。
87 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:43:39 ] そういう意味では82のPerlでソース生成と言うのも立派なメタプログラミング。
88 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:04:07 ] >>82 そんなあなたに constexpr@C++0x
89 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:06:00 ] 一方D言語はsinを定数として畳み込んだ。
90 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:09:59 ] 静的に実行できる関数は静的に実行してしまう。 D は中々のものだ。
91 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:35:24 ] D言語って誰が生みの親なの?
92 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:36:25 ] 昔borlandで働いてた人
93 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:37:28 ] をるたん
94 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:40:52 ] >>92 じゃあ流行らないな
95 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:43:40 ] ボーランドはちがくね?
96 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 18:26:21 ] >>82 まあC++のテンプレートはメタプログラミングのために設計されてないからねえ。 マクロらしいマクロを持った言語なら、かなり高度なメタプログラミングをやってても 普通のコードの2倍やそこらの時間でコンパイルできる。 Lispの世界じゃ40年前からメタプログラミングが当たり前だし、 DOSの世界ではMASMのマクロで構造化なんてのが流行った。
97 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 18:35:23 ] ライブラリ作るときは主流になりそうだけどな。 てか、もうなってるか。 でもschemeのほうが言語機能としてcons listとか があるから、より簡潔でストレス感じない。 C++のTMPはいかんせん表現がキモ過ぎる。
98 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:15:57 ] そこで constexpr ですよ
99 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 02:22:19 ] こんなの作ってみた。 自分のプログラムでは活用できてるからいいんだけど、意外と汎用性ないな…… struct UniqueNumber { template<class type_t> static unsigned int number() { static unsigned int n(count()); return n; }; private: static unsigned int count() { static unsigned int c(0); return c++; }; }
100 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 01:51:48 ] >>83 プログラムを作るプログラムをプログラムしてみようって事だよ 当然、(プログラムをつくるプログラム)をつくるプログラムもね。 どこまででも逝ってくれ
101 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 16:49:57 ] >>99 typeidの速度が気になる場面で使うのかな?
102 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:07:03 ] >>99 struct UniqueNumber { static unsigned int number() { return count(); } private: static unsigned int count() { static unsigned int c; return c++; } } これでよくない?
103 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:09:25 ] >>102 全然よくない。
104 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:13:44 ] >>103 何で? type_tテンプレートパラメータ使われてないよ。
105 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:16:00 ] >>104 UniqueNumber::number<A>()とかUniqueNumber::number<B>()みたいな使い方するんでしょ。 で、テンプレートに渡した型毎に一定のユニークな値が返ってくると。
106 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:33:05 ] ああそうか でも cout << UniqueNumber::number<int>() << endl; cout << UniqueNumber::number<int>() << endl; cout << UniqueNumber::number<int>() << endl; cout << UniqueNumber::number<char>() << endl; cout << UniqueNumber::number<char>() << endl; cout << UniqueNumber::number<float>() << endl; やったら 0 0 0 1 1 2 となった。 何で、0 1 2 0 1 0にならないのかな?
107 名前:106 mailto:sage [2008/02/25(月) 17:38:05 ] わかりますた。なるほど。
108 名前:99 mailto:sage [2008/03/01(土) 03:50:23 ] 応用例作ってみた。 ttp://fiercewinds.net/siki/pub/2008/03/01_032951/ 継承で登録を強制できれば便利そうなんだけどなぁ。 あとファクトリ関数みたいに関数の引数とか戻り値にそのクラスを含む場合は、こんな大掛りな仕掛けは不要みたい。 ……それ以前に言語側で何とかして欲しいよな。こんなの。
109 名前:デフォルトの名無しさん mailto:sage [2008/03/15(土) 21:46:47 ] ちょっと質問です。 外部リンケージについて詳しく書いてある解説ってある? 具体的には関数内クラスをテンプレートパラメーターにして渡したいんだけどね。 externでも上手く行かんし……
110 名前:デフォルトの名無しさん mailto:sage [2008/03/15(土) 21:51:35 ] それはそもそも無理じゃまいか?
111 名前:106 mailto:sage [2008/03/15(土) 22:19:26 ] >>109 規格上不可能
112 名前:デフォルトの名無しさん [2008/04/10(木) 23:41:05 ] メタプログラミングしてると脳汁でます
113 名前:デフォルトの名無しさん mailto:sage [2008/04/11(金) 00:39:33 ] なぜjavaやC#でtemplateが外されたか 不要物だからw
114 名前:デフォルトの名無しさん mailto:sage [2008/04/11(金) 00:58:20 ] なぜJavaやC#でgeneri(ry
115 名前:デフォルトの名無しさん mailto:sage [2008/04/11(金) 01:01:28 ] 失ってから大切さに気付くものです
116 名前:デフォルトの名無しさん [2008/05/07(水) 22:32:52 ] boost::mplとか使ってるコードで見る、 _1, _2ってどうやって実現してるんですか?
117 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:35:39 ] ソース読めばいいだろw
118 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 23:07:19 ] defineかtypedefだったかな
119 名前:デフォルトの名無しさん mailto:sage [2008/05/09(金) 15:11:22 ] テンプレートで配列指定された場合エラーにする方法ってあるんでしょうか?
120 名前:デフォルトの名無しさん mailto:sage [2008/05/09(金) 18:55:50 ] type_traitsのis_arrayとBOOST_STATIC_ASSERTを組み合せればいけるはず
121 名前: mailto:sage [2008/05/14(水) 07:27:15 ] g++とVC2008どっちがテンプレート学ぶにはいいですか? どっちがより完璧にテンプレートをコンパイルできますか?
122 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 07:35:58 ] どうみてもg++
123 名前: mailto:sage [2008/05/14(水) 09:16:34 ] >>122 ありがとう。
124 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 02:14:25 ] テンプレートの実体化でテンプレート引数を特殊化にマッチさせる過程って Prologの統一化と似てる気がする
125 名前:デフォルトの名無しさん mailto:sage [2008/06/01(日) 02:40:06 ] >>99 のような型にユニークな数字を割り当てるのをコンパイル時にできないでしょうか? boost::fusion::vectorに格納されている型をすべてユニークな型にしたいとき、 単純に片っ端から同じ型が含まれていないか調べると計算量がO(n*n)(nは格納されている型の数)になるかと思います。 そこで、boost::fusion::vectorをboost::mpl::sortしてboost::mpl::uniqueすれば sortが平均O(n*log(n)), uniqueがO(n)だとすると先に説明した単純な方法より高速に計算する事ができるかと思います。 ですが一般的な型に対して順序関係はないのでboost::mpl::sortを実行することができません。 そこで>>99 のような型毎に静的にユニークな数字を割り当ててboost::mpl::sortを適応させることができるようにしたいです。 長くなりましたが、皆様宜しくお願いします。
126 名前:デフォルトの名無しさん mailto:sage [2008/06/01(日) 04:09:25 ] ムリじゃない? 分割コンパイルみたいな局面を考えると、ある型にユニークな数字が割り当て済かどうかすら判らんと思う。 リンカと連携すればいいんだろうけど、C++の規格はそこまで考えてないんじゃない? 指定された型のstaticポインタを用意してそのアドレスを使えばなんとかなるかも知れんが、どうなんだろ? void*にキャストすれば比較もできるんじゃね?
127 名前:デフォルトの名無しさん mailto:sage [2008/06/01(日) 18:57:02 ] そもそも数字の割り当て方を制御できないとソートする意味がなくね? どう割り当てたいの?
128 名前:デフォルトの名無しさん mailto:sage [2008/06/01(日) 19:09:24 ] どんな数値でもいいから割り当ててしまえば二分探索の恩恵を受けられるってことだろ
129 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 02:49:12 ] >>126 やはり無理なんですかね。 アドレスを得られるのはコンパイルのテンプレートの展開等の後の段階になるので無理だと思うのですが。 >>127 >>125 で書いてある通り,型の集合の中に同じ型が含まれないようにすることが目的なので boost::mpl::uniqueする前に同じ型が連続して並ぶようにboost::mpl::sortの結果が返ればよいのです。 ですので割り当てたい数字は型毎にユニークであれば何でもよいのです。アドレスもOK養豚場です。 >>128 二分探索を使って同じ型を消す処理をしてもO(n*log(n))で計算できそうですね。 そういう方法は考えていませんでした。
130 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 03:18:17 ] >>125 で書いた事をもう少しわかりやすく説明すると 例えば以下のような型があったとき、 typedef boost::fusion::vector<char, int, char, int> vec; vecから重複する型を削除してユニークな型を保持するようにしたいのです。 typedef hoge<vec>::type unique_vec; //こんなhogeを欲しているのです. BOOST_MPL_ASSERT(( boost::is_same<unique_vec, boost::fusion::vector<char, int> > )) それで、以下の仮想コードのような方法を使とO(n*n)の計算時間が掛ります. for i∈vec for j∈vec もしiとjが同じ型だったらjをvecからはずす. そこで typedef boost::mpl::unique< boost::mpl::sort< vec, piyo>::type, is_same<_1, _2> >::type unique_vec; とやればO(n*log(n))の計算量で済みます。 そこで上記のpiyoに相当するMetafunction class、 すなわち型に順序関係を与える方法を教えて貰いたいのです。 >>128 referenceにはboost::mpl::findは線形時間が掛ると書いてあるので 二分探索するには自分でコードを書かないといけないようです.
131 名前:ヽ・´∀`・,,)っ━━━━━━━┓ mailto:sage [2008/07/09(水) 14:39:37 ] >>124 静的(コンパイル時完全評価)だけどな。 VIPのスレで昔テンプレートでアッカーマン関数の問題解こうとしてドツボにハマった奴がいた。
132 名前:デフォルトの名無しさん [2008/07/16(水) 20:46:07 ] 『Modern C++ Design―ジェネリック・プログラミングおよびデザイン・ パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series) 』 ってのを読んでいる素人だけど、69ページのMostDerivedってのが マジ分からん。今日、朝、昼、晩を合計で4時間ぐらい考えたんだが どういう流れでこれで継承関係でいちばんの派生なのを特定できるのか 分からん。誰か分かる人いませんか?
133 名前:デフォルトの名無しさん [2008/07/16(水) 21:05:22 ] 結局、 typedef typename MostDerived<Tail, T>::Result Candidate; では、再帰的に展開が繰り返され、MostDerived<NullType, T>に なり、CandidateはTにしかなりえない 続く、 typedef typename Select< SUPERSUBCLASS(Candidate, Head), Head, Candidate >::Result ResultではCandidateはTと読み替えられるわけで TがHeadのスーパークラスなら結果はHead HeadがTのスーパークラスなら結果はTとなる これじゃ全然ダメじゃね? ググってみたけど、MostDerivedはダメだったって話を他でも見かけたよ
134 名前:デフォルトの名無しさん mailto:sage [2008/07/26(土) 05:07:27 ] >133 >typedef typename MostDerived<Tail, T>::Result Candidate; >では、再帰的に展開が繰り返され、MostDerived<NullType, T>に >なり、CandidateはTにしかなりえない どの段階で T にしかなりえないと思ってるのか分からないけどちゃんと再帰的に展開できてる? MostDerived<TypeList<T0, TypeList<T1, NullType> >, T>::Candidate # Head=T0, Tail=TypeList<T1, NullType> →MostDerived<TypeList<T1, NullType>, T>::Result # Head=T1, Tail=NullType →Select<SUPERSUBCLASS(MostDerived<NullType, T>::Result, T1), T1, MostDerived<NullType, T>::Result>::Result # MostDerived<NullType, T>::Result → T →Select<SUPERSUBCLASS(T, T1), T1, T>::Result 結果として、 MostDerived<TypeList<T0, TypeList<T1, NullType> >, T>::Result →Select<SUPERSUBCLASS(Select<SUPERSUBCLASS(T, T1), T1, T>::Result, T0), T0, Select<SUPERSUBCLASS(T, T1), T1, T>::Result>::Result T と T1 を比較した結果、と T0 を比較した結果が返ってくる。
135 名前:デフォルトの名無しさん mailto:sage [2008/08/30(土) 14:17:24 ] ttp://www.fides.dti.ne.jp/~oka-t/cpplab-tips-1.html に ローカルクラスの静的関数は関数テンプレートの引数に指定可能というのがあるのですが、 ローカルクラスのクラス内クラスの場合どうなりますか? 役立たずVC8だとノーチェックでOKにしたので確認できませんでした。 void func() { struct local { void operator()(int x) { cout << x << endl; } static void f( int x ) { cout << x << endl; } struct func { void operator()(int x) { cout << x << endl; } }; }; std::vector<int> v; v.push_back(0); v.push_back(1); v.push_back(2); for_each( v.begin(), v.end(), local::f ); for_each( vbegin(), v.end(), local::func() ); // これはどうなるの? for_each( v.begin(), v.end(), local() ); //ホントはエラーのはず。VC8.0はOK…… }
136 名前:デフォルトの名無しさん mailto:sage [2008/08/30(土) 15:00:49 ] VCだと言語拡張を有効にすることで関数内構造体もテンプレート引数に渡せてしまう。 俺はそれが嫌で言語拡張を無効にしてる。
137 名前:デフォルトの名無しさん mailto:sage [2008/08/30(土) 16:07:38 ] >136 サンクス。無効にすると両方ともNGになりますね。 言語拡張を無効にすると色々なライブラリが使い物にならなくなるから、 さすがにそこまでストイックにはなれないなぁ……
138 名前:デフォルトの名無しさん mailto:sage [2008/08/31(日) 17:08:18 ] 言語拡張機能が使用された場合に警告を出すってオプションがあったと 思うんで、取り合えずそれONにしとけば?
139 名前:デフォルトの名無しさん mailto:sage [2008/08/31(日) 17:37:41 ] そんなもの存在しません。
140 名前:デフォルトの名無しさん [2008/10/14(火) 17:41:25 ] 工エエェェ(´д`)ェェエエ工工
141 名前:デフォルトの名無しさん mailto:sage [2008/10/18(土) 22:01:41 ] template <template <class Created> class CreatePolicy> これのtemplate <class Create>部分の採用がヨクワカラナイ どこかに良い説明のってないっすか
142 名前:デフォルトの名無しさん mailto:sage [2008/10/19(日) 02:40:29 ] とりあえず検索用語だけ template-template-parameters
143 名前:デフォルトの名無しさん mailto:sage [2008/10/24(金) 23:27:12 ] class Hoge { template <int X> void Fuga() {...} }; テンプレート引数Xの値を、静的な値として集めることってできますか? 具体的には、呼び出されたFugaのうち、最も大きいXを取得して、別のクラステンプレートに渡すとか。
144 名前:デフォルトの名無しさん mailto:sage [2008/10/26(日) 01:21:18 ] >>143 パッとみて無理っぽいうえにコンパイル単位をまたぐ場合を考えるとさらに無理っぽい。
145 名前:デフォルトの名無しさん mailto:sage [2008/10/30(木) 20:35:00 ] (´;ω;`)
146 名前:デフォルトの名無しさん mailto:sage [2008/11/26(水) 04:36:26 ] >>142 横だけど、meta templateでググっても見つからなく困っていたので助かった。 そういう用語だったのか…
147 名前:99 [2009/01/12(月) 20:40:07 ] まいど。 どうしても欲しくなったのでマルチメソッドを実装したんだけど、もっと効率的になる改善点てあります? (詳細)ttp://cvs.sourceforge.jp/view/siki/siki/src/holder.hpp?rev=1.1&view=markup (解説)ttp://fiercewinds.net/siki/pub/2009/01/12_191240/ 解説がクソなのは置いといて下さい。 もっと良い実装があればそれも紹介して欲しいです。 個人的には ・いちいち登録しなきゃいけないのが面倒。 ・トランポリン関数を保持する配列が疎になるのでメモリ効率が悪そう…… というところが気になるところです。
148 名前:99 mailto:sage [2009/01/13(火) 00:44:59 ] ちょっとだけ >147を修正。 登録をヘルパークラスに任せることにしました。少しはスマートに見えるけど、受け入れる型を 全部登録しなきゃいけないのは変わらず…… 色々と考えてみたけど、どうやっても仮想関数に型情報は渡せなさそうね……。
149 名前:99 mailto:sage [2009/01/13(火) 01:15:20 ] リンク間違えてたので修正します。 (詳細)ttp://cvs.sourceforge.jp/view/siki/siki/src/holder.hpp?view=markup
150 名前:デフォルトの名無しさん mailto:sage [2009/01/19(月) 20:24:39 ] ポリシーによるプログラミングで質問です。 適当な乱数を発生させるTraitsクラスを何個か定義します。 struct r {int rdm(){return rand()%128;}}; struct rs{int rdm(){return rand()%7+60;}}; そんで、Traitsを使うクラスがこれ。ここまでは順調です。 template <class T=r> class R{int rdm(){return T.rdm();}}; この後、rdm関数が引数を持つようなTraitsを加えようとすると型があわないため困りました。 しかし、こういうケースは良くあるのではないかと思います。 struct rc{int rdm(int n){return n*(rand()%128);} 少し悩んでこんな解を出して見たのですが こういう場合、みなさんどのように解決されますか? template <int N> struct rt{int rdm(){return N*(rand()%128);} R<rt<3> > r; ↑この場合、途中で引数を変えたいと思った場合毎回インスタンスを作る必要がある点が若干面倒です。 また、整数引数しか使えません 関数でやる場合は引数変更は楽ですが Traitsにあたるものが増えてくると関数の組み合わせ爆発が大変です。 手法にこだわりはないのでこのやり方が楽、などあればきいてみたいです。
151 名前:デフォルトの名無しさん mailto:sage [2009/01/19(月) 20:35:21 ] struct r{ int rdm(){ return rand() % 128; } }; struct rs{ int rdm(){ return rand() % 7 + 60 } }; template<typename Ty> struct rc{ Ty value; int rdm(){ return value * (rand() % 128); } }; 後はrc::valueのゲッター書くなりセッター書くなりしろ。
152 名前:150 mailto:sage [2009/01/19(月) 21:33:25 ] >>151 ありがとう。参考にします。
153 名前:デフォルトの名無しさん mailto:sage [2009/01/19(月) 23:44:40 ] STL コンテナでアロケータを指定する方法を真似するのは、何か都合が悪いの? template <class T=r > struct R { T t; R( const T & t_ = T() ) : t(t_) {} int rdm() { return t.rdm(); } }; R< random_with_number > rn( random_with_number(3) );
154 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 14:16:13 ] >>153 これは良いですね!頂きます。 使ってみて、若干罠というか、引数なし版はプロトタイプ宣言と勘違いされるため R<r> a(r()); //error こうする必要があるんですね(もっと良いやり方があるのかは知らないですが・・) R<r> b(*(new r())); これを参考に、少し書き換えて見ました struct b {virtual int rdm(){return 0;}}; struct r:b {int rdm(){return rand()%128;}}; struct rs:b{int rdm(){return rand()%7+60;}}; struct rc:b{ int val; rc(int n) : val(n){} int rdm(){int tmp=rand()%7;if(tmp%val==0){return tmp;}else{return rdm();}}}; template <class T=b > struct Q { T* t; Q( T* t_) : t(t_){} int rdm() { return t->rdm();} }; Q<> a(new rc(3)); Q<> b(new r());
155 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 14:55:23 ] >>154 > R<r> a(r()); //error R<r> a((r())); でいけるよ
156 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 15:15:23 ] ほんとだ、こっちのが短くていいですね。
157 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 15:27:24 ] struct b::rdm() を virtual にするなら template にする意味は無いと思うのだけれども・・・。 struct Q { // non template version b * t; Q( b * const t_) : t( t_ ? t_ : new b ){} ~Q() { /* Do you want to delete t ? */ int rdm() { return t->rdm();} }; でいいでしょ。 ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。
158 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 16:08:53 ] 単に左辺を書かなくても良くなるぐらいの気持ちで書き直したんですが そもそもtenmplate無くても動きますね・・難しいなぁ ある意味、template使わなくてもポリシーベースのプログラミングが出来るわけですね あえてtemplateを使う利点が整理できてないので考えてみます。 >ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。 シンプルながら、これは説得力ありますね
159 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 16:43:24 ] >>155-156 R<r> a;でいいじゃない。
160 名前:157 mailto:sage [2009/01/24(土) 17:11:30 ] >>158 > あえてtemplateを使う利点が整理できてないので考えてみます。 157 では、t->rdm() は、コンパイラによって必ず仮想関数呼び出しコードが出力される。 テンプレートバージョンでは、定数を返す場合などには、もしかしたらコードは全く無くなるかもしれない。 153 程度で大げさな、と思うかもしれないが、これもメタプログラミングだ。 実行時に通過するコードではなく、コンパイルで出力されるコードを、引数で変えることが出来るから。 C のプリプロセッサマクロでも出来るけど、C++ template は型チェックとそこから派生する特殊化された型の選択が強み。 > シンプルながら、これは説得力ありますね 157 の Q のデストラクタを見てみて。 あと、メモリ消費量が減るかも。 ところで、154 の記法の問題は、cl, bcc, gcc で試したけど、 R<r> a( (r)r() ); が一番互換性が高いようだ。 もちろん 159 でいいんだけどw 引数を明示したいならね。
161 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 18:32:50 ] > R<r> a( (r)r() ); たまたま‘r’という短い名前だからそれでいいかもしれんが、 名前が長かったり、さらにネストしたテンプレートクラスだったりすると 書くのも面倒だよ。 他にも R<r> a = R<r>(r()); とか考えられるけど、やっぱり R<r> a((r())); が楽だと思うけどね。
162 名前:デフォルトの名無しさん mailto:age [2009/02/14(土) 00:35:29 BE:1969877186-2BP(0)] age
163 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 22:20:49 ] テンプレートの引数にテンプレート渡せるのか〜知らなかった。 これで大分やれることが広がったぜ。ウヒヒ ていうか、テンプレートの完全な仕様ってどこに行けばみれるの?
164 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 22:27:47 ] >>163 ちょうどこっちでその話があったところ。 pc11.2ch.net/test/read.cgi/tech/1234420483/758-767