1 名前:デフォルトの名無しさん mailto:sage [04/11/25 21:11:32] C++ のジェネリックプログラミングの話をしましょう。 以下のスレッドを統合するスレです。 STLスレッド Part1 pc.2ch.net/tech/kako/1004/10042/1004287394.html Part2 pc3.2ch.net/tech/kako/1026/10267/1026793823.html 【C++】Boost使い集まれ! pc3.2ch.net/test/read.cgi/tech/1033830935/ (html化待ち?) Generic Programming with C++ Template pc.2ch.net/tech/kako/1008/10085/1008593126.html 【C++】template 統合スレ -- STL/Boost/Loki, etc. pc2.2ch.net/tech/kako/1037/10377/1037795348.html 【C++】template 統合スレ -- Part2 pc2.2ch.net/test/read.cgi/tech/1047978546/ (html化待ち) 【C++】template 統合スレ -- Part3 pc5.2ch.net/test/read.cgi/tech/1066493064/ (html化待ち) 【C++】template 統合スレ -- Part4 pc5.2ch.net/test/read.cgi/tech/1083550483/ (html化待ち) 【C++】template 統合スレ -- Part5 pc5.2ch.net/test/read.cgi/tech/1091522597/ 関連スレ、その他リンクは >>2-5 あたりに。
111 名前:デフォルトの名無しさん mailto:sage [04/12/25 20:04:43] 踊る阿呆に見る阿呆、同じ阿呆なら踊らにゃソンソン
112 名前:デフォルトの名無しさん mailto:sage [04/12/25 21:42:20] 踊らにゃシャンソン
113 名前:デフォルトの名無しさん mailto:sage [04/12/25 22:01:15] >>111 必ずどちらかの阿呆であるという無理な前提で人を煽るその言葉は大嫌いだ。
114 名前:デフォルトの名無しさん mailto:sage [04/12/25 22:24:27] 2択でもなく決め付けだしな 詭弁だ
115 名前:デフォルトの名無しさん mailto:sage [04/12/25 22:27:59] なんで踊るよりも見る方が損なのかがわからん。 踊ったら疲れるだけなのに。
116 名前:デフォルトの名無しさん mailto:sage [04/12/25 22:47:49] 理論(見る)より実践(踊れ)てこと
117 名前:デフォルトの名無しさん mailto:sage [04/12/25 22:51:29] >>115 踊ることが楽しいと言いたいのだろう。
118 名前:デフォルトの名無しさん [04/12/25 23:20:36] >>101 VC++ 7.1 だと unsigned T1 のような書き方は構文エラーになりました。
119 名前:デフォルトの名無しさん mailto:sage [04/12/26 00:16:22] C++Templateの便利な機能のうち Javaでは実現できないことってなんなのかを 教えてください。
120 名前:デフォルトの名無しさん mailto:sage [04/12/26 00:17:25] 特殊化
121 名前:デフォルトの名無しさん mailto:sage [04/12/26 00:18:39] ていうかほぼ全部?
122 名前:デフォルトの名無しさん mailto:sage [04/12/26 01:13:48] >>119 使ってすぐ分かるのは、コンテナから取り出すときにナローイング変換しなくていいこと。
123 名前:120 mailto:sage [04/12/26 01:16:18] あれ? Java Genericsかと思ったけど、Javaか…
124 名前:デフォルトの名無しさん mailto:sage [04/12/26 04:53:50] JavaのGenericsってただの自動キャストでそ? C++のtemplateとは比較にならないのでは・・・
125 名前:デフォルトの名無しさん mailto:sage [04/12/26 08:56:50] .NETのgenerics、試みは面白い。
126 名前:デフォルトの名無しさん [04/12/26 13:31:14] で、結局具体的にどんなことがJavaにできなくて C++で出切るんですか? C++ではこんなに簡単に書けるのに Javaで書くとこんな風になっちゃうって例を 出していただけると助かります。 いろいろ考えたんですが、特別優れた使い方ってのが 思いつかなかったので。 もしかして、ないのかな・・・
127 名前:デフォルトの名無しさん mailto:sage [04/12/26 20:01:11] クマー
128 名前:デフォルトの名無しさん mailto:sage [04/12/26 20:13:40] .| | | | | | | | .| | | レ | | | | ∩___∩ | | | J | | | | ノ\ ,_ ヽ .| レ | | レ| / ●゛ ● | .J し | | | ∪ ( _●_) ミ .| し 彡、 |∪| | .J / ∩ノ ⊃ ヽ ( \ / _ノ | | \ " / | | Javaしらね。覚える気もねえし \ / ̄ ̄ ̄ /
129 名前:デフォルトの名無しさん mailto:sage [04/12/26 20:56:55] >>126 Java Genericsは分かるの?
130 名前:デフォルトの名無しさん mailto:sage [04/12/28 00:49:18] >>126 「オブジェクト指向をベース」にプログラムを書いた場合 JavaのGenericsで全てが事足りる。
131 名前:デフォルトの名無しさん mailto:sage [04/12/28 01:22:25] 速度以外はな。
132 名前:デフォルトの名無しさん mailto:sage [04/12/28 05:44:30] 素人が首突っ込んで申し訳ないが Javaには専用プラットフォーム必須なんだよね? 要はエミュレータ?
133 名前:デフォルトの名無しさん mailto:sage [04/12/28 08:33:23] >>132 プラットフォームの意味わかってんのか?
134 名前:デフォルトの名無しさん mailto:sage [04/12/28 12:28:32] >>126 Lokiのような変態的なライブラリは無理じゃないの?Generics知らんけど。
135 名前:デフォルトの名無しさん mailto:sage [04/12/28 13:19:32] その変態なLokiなんですけど、TYPELISTって動作遅くしないですか? 継承によって、多義性をサポートさせるのはよい。 コンパイル時にその多義性を作り出すのも良い。 けど、継承って、実行速度おそくなりませんか?
136 名前:デフォルトの名無しさん mailto:sage [04/12/28 13:24:09] >>134 あれはオブジェクト指向を捨ててるからな。 オブジェクト指向で書き直せばもっときれいなのが作れるよ。
137 名前:デフォルトの名無しさん mailto:sage [04/12/28 13:38:33] >>135 Modern C++ Designを読めば分かるけど、 LokiのPolicyは仮想関数を使ってないから…
138 名前:デフォルトの名無しさん mailto:sage [04/12/28 13:42:22] >>135 TYPELISTはコンパイル時のみ。 継承なしで巨大ライブラリを作れる人、使える人はそうしたら良かろう。 Cで書いてあるgtk+みたいなのでも継承しているけどね。
139 名前:デフォルトの名無しさん mailto:sage [04/12/28 13:42:58] 大抵は問題にならん
140 名前:デフォルトの名無しさん mailto:sage [04/12/28 14:51:39] lokiはデザパタではなくてboost::mplに似ているわけか。
141 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:23:42] たくさんのレスに感謝。 >137 Modernは読んでます。内容を完全に理解したとは言いがたいですが。 けれども、Efficient読んでるとvirtual使わない継承でも動作遅くなるよ〜。 と書いてあるもので。 「本質的な問題ではない。」が結論なんですけどね。 >138 その通りです。 継承無しでライブラリの作成…作ったことありませんがゾッとします。 >139 >大抵は問題にならん。 継承しまくったオブジェクトを生成&削除しまくるプロジェクトとか (サーバー用途?)ではどうでしょうか? ModernのTYPELISTの継承構造見ていると、継承の無駄が多い気がして。 p237のクラス階層とかってつまりは。 class AbstractEnemyFactory :public AbstractFactoryUnit<Soldier>, public AbstractFactoryUnit<Monster>, public AbstractFactoryUnit<SuperMonster> なわけで。 実際に巨大プロジェクトの現場を経験したことのない人間の戯言ですが。
142 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:27:43] >実際に巨大プロジェクトの現場を経験したことのない人間の戯言ですが。 自覚しているんなら黙れ。っーつか氏ね。
143 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:28:43] >>142 お前こそ黙っとけよ。
144 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:31:01] >>143 バーカ
145 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:38:54] >っーつか氏ね。 OK。発音してみよう。
146 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:48:24] >>141 それ、TYPELISTなしで書いた方が可読性悪いでしょ。 TYPELISTは実行時に負担ないしね。コンパイル時にやるから。 typeid listじゃないから。
147 名前:デフォルトの名無しさん mailto:sage [04/12/28 15:51:47] >継承しまくったオブジェクトを生成&削除しまくるプロジェクトとか >(サーバー用途?)ではどうでしょうか? メモリ確保&解放は一瞬。メモリに書き込むことは多少重いけど。 ただ、ゲームなんかのメモリ資源が超少ない環境では メモリのフラグメントなんかが起こって、メモリが足りなくなることはある。
148 名前:デフォルトの名無しさん mailto:sage [04/12/28 16:01:22] いや、new/deleteは重いけど、 継承しているしていないに関係ない。 継承して複雑な部分を作り出す構造だと、 一つのオブジェクトの中にまとめられるから、 利用するメモリチャンクの数が減ることも考えられる。 Cでやると、ポインタの嵐になって別々の構造体になるから、 malloc/freeを寄り頻繁にする必要がある(事が多い)。 とりあえず、135は、 ・templeteが、compile時のみ働くものであること ・詳解C++(いわゆるAnnotated)を読んで、継承のメモリ利用 を勉強しろ。 分からない奴はいつまでたっても設計ができない。
149 名前:デフォルトの名無しさん mailto:sage [04/12/28 16:03:14] >>148 > Cでやると、 「継承しないでやると、」の方がいいかな。 compositionとinheritanceの違いはAnnotated読んで。
150 名前:デフォルトの名無しさん mailto:sage [04/12/28 16:58:14] みんなRubyのこと嫌いなの?
151 名前:135 mailto:sage [04/12/28 18:54:45] 自分でTYPELISTでAbstractFactoryを組んで、それをいじくりまわしてみました。 結果:変わらないですね… なんか狐につままれた感じのするのは私だけでしょうか。 >・詳解C++(いわゆるAnnotated)を読んで、継承のメモリ利用 を勉強しろ 多分これが今の私に必要なんでしょうね。 はい。いろいろとがんばってみます。 皆様ありがとうございました。
152 名前:151 mailto:sage [04/12/28 22:14:45] >結果:変わらないですね… コンパイル時間が変わっていると思うけど……
153 名前:デフォルトの名無しさん [04/12/29 01:08:18] mmap+boost で、データ構造のシリアライズがやりたいです。 具体的には、 1、データファイルをmmap で巨大なヒープとしてメモリに貼り付ける。 なお、このとき、毎回同じメモリアドレスに貼り付ける必要性がある。 2、boost の new をいじくり、すべてそのmmapされたヒープの中でのみ allocate されるようにする。 以上で、データ構造がそっくりシリアライズできるような気がするのですが、 どうやってやればいいでしょうか。
154 名前:デフォルトの名無しさん mailto:sage [04/12/29 01:32:26] boost::serialize使えばいいのに
155 名前:デフォルトの名無しさん mailto:sage [04/12/29 01:33:17] boost::serializationだった
156 名前:デフォルトの名無しさん [04/12/29 03:49:42] ええっと、それだと、一度すべての変数をずるずるっと舐めることになりますよね。 そうじゃなく、効率も考え、変数空間全体をmmap でファイルに貼り付けたいんです。
157 名前:デフォルトの名無しさん mailto:sage [04/12/29 03:53:06] 舐めるならレロレロとかチュパチュパじゃないか? ずるずるってナニ?
158 名前:デフォルトの名無しさん mailto:sage [04/12/29 03:54:17] つーか >毎回同じメモリアドレスに貼り付ける必要性がある。 これで破綻してるとは思わないのか
159 名前:デフォルトの名無しさん [04/12/29 05:06:16] それはすくなくともLinuxなら可能です。 とくに、今後の64bit Linuxなら、アドレス「空間」はいくらでも余ってるので、 何の問題もないでしょう。
160 名前:デフォルトの名無しさん mailto:sage [04/12/29 17:23:10] >>159 ^^
161 名前:デフォルトの名無しさん mailto:sage [04/12/29 17:48:45] >>153 やりたいようにやればあ。 絶対アドレス依存じゃないヒープ保存で有名なのはEmacsとTeX。 絶対アドレスに依存するのはちょっと面倒だね。 C++のオブジェクトを直接張り付けるんじゃなくても、 wrapper classで仮想的に扱えるよね。
162 名前:デフォルトの名無しさん mailto:sage [04/12/29 21:34:37] おまえら、「boost の new」の意味はわかってるのか? 漏れにはわからん。
163 名前:デフォルトの名無しさん mailto:sage [04/12/29 21:39:05] 「boostで使うnewとかもひっくるめて自分でglobalなoperator new()をオーバーライドしちゃいます」 という意味だと思ってた
164 名前:デフォルトの名無しさん mailto:sage [04/12/29 21:53:12] >>163 そうなると、「mmap+boost で」っていうのがわからん。 boost も template も関係ないじゃないか。
165 名前:デフォルトの名無しさん mailto:sage [04/12/29 21:58:22] ううむ。確かに。 boostの機能のキの字も使ってないもんなぁ。
166 名前:161 mailto:sage [04/12/29 22:00:47] そもそもシリアライズじゃないし(w
167 名前:デフォルトの名無しさん mailto:sage [05/01/04 00:56:10] 知り合いs
168 名前:デフォルトの名無しさん mailto:sage [05/01/06 00:15:21] GC(参照カウント方式)に使えるポインタオブジェクトで オブジェクトのconst修飾が参照先のconst修飾に対応した クラスってないでしょうか Boost流だとこんな↓感じ? template<typename T> class my_shared_ptr : protected boost::shared_ptr<T> { public: const T * operator->() const { return __super::operator->(); } T * operator->() { return __super::operator->(); } // other functions implementation... }; おねがいします
169 名前:デフォルトの名無しさん mailto:sage [05/01/06 00:22:41] >>168 そんな感じでいいんじゃないの?
170 名前:168 mailto:sage [05/01/06 00:26:23] はい、ありがとうございます ただ、既存のライブラリでいいのはないかと思いまして・・・
171 名前:デフォルトの名無しさん mailto:sage [05/01/06 01:16:46] >>170 Boost は「既存のライブラリ」以外の何だというのかね?
172 名前:デフォルトの名無しさん mailto:sage [05/01/06 02:12:11] >>168 ちなみにshared_ptr<T const>を嫌う理由は何ですか?
173 名前:デフォルトの名無しさん mailto:sage [05/01/06 06:31:17] 重い
174 名前:デフォルトの名無しさん mailto:sage [05/01/06 10:28:20] プログラム全体の動作に致命的なほど遅くはなんねぇよ
175 名前:デフォルトの名無しさん mailto:sage [05/01/06 10:56:57] 何の要件もなしに「重い」と言って切り捨てる >173 も、 何の前提もなしに「致命的なほど遅くはなんねぇ」という >174 も、 同じ程度に浅はかである。
176 名前:デフォルトの名無しさん mailto:sage [05/01/06 11:01:20] >>175 それを否定してしまったら何もかけなくなっちゃうよ。
177 名前:デフォルトの名無しさん mailto:sage [05/01/06 11:09:22] >>176 175が何を否定してるんだ?
178 名前:デフォルトの名無しさん mailto:sage [05/01/06 11:10:18] 日本の将来
179 名前:電波系赤の他人 mailto:sage [05/01/06 11:13:22] 俺も人格も否定しているような気がする。
180 名前:デフォルトの名無しさん mailto:sage [05/01/06 18:37:00] >>172 嫌というほどでもないんですが、 コンパイルが遅そうとか、その程度です const my_shared_ptr<T> get_obj_ptr() const; my_shared_ptr<T> get_obj_ptr(); より、 shared_ptr<T const> get_obj_ptr() const; shared_ptr<T> get_obj_ptr(); の方が意味的に適切だとは思うんですが 自分で書くのめんどうなので、とりあえずboost::shared_ptrでいいや・・・
181 名前:デフォルトの名無しさん mailto:sage [05/01/06 20:30:30] こういうのどうですか? #defineBEGIN_JUNK( __Super, __Misc ) \ template< int _N >struct __Junkyard{ enum { _junk_no = __Junkyard< _N - 1 >::_junk_no }; }; \ template<> \ struct __Junkyard< __LINE__ > : public __Super::_junk \ { \ enum { _junk_no = __LINE__ }; \ typedef __Super::_junk _prev; \ __Misc; \ }; \ typedef__Junkyard< __LINE__ >_start_junk; \ #defineREDEF_JUNK( __Misc ) \ template<> \ struct __Junkyard< __LINE__ > : public _prev_junk \ { \ enum { _junk_no = __LINE__ }; \ typedef _prev_junk_prev; \ __Misc; \ }; \ #defineEND_JUNK() \ typedef_cur_junk_junk; \ 長いので詳細は↓に書いてあります。 www2.odn.ne.jp/freelife/Junkyard.htm 割と使えると思うんだがどうだろう?
182 名前:デフォルトの名無しさん mailto:sage [05/01/06 22:08:44] >181 マクロで実装してるreflection系ライブラリの提案見るたびに思うんですけれど マクロとテンプレートの相性の悪さはどう対処するつもりなんでしょうか? 毎回typedef?(面倒)BOOST_PP_SEQ?(カッコ悪い)variadic macro待ち?(いつ出る?) struct Sample2 { typedef Sample2 _self; BEGIN_JUNK( ZJunkBase, typedef ZTypeList<> _data_member1; ); DATA_MEMBER( 1, my_class<char, int>, x ); END_JUNK(); };
183 名前:181 mailto:sage [05/01/06 22:39:57] >>182 言いたいことには同意 対処って程ではないが、苦肉の策でこんなことやってる #define $ , struct Sample2 { typedef Sample2 _self; BEGIN_JUNK( ZJunkBase, typedef ZTypeList<> _data_member1; ); DATA_MEMBER( 1, my_class<char $ int>, x ); END_JUNK(); }; はげしくかっこ悪いが w
184 名前:デフォルトの名無しさん mailto:sage [05/01/06 22:59:24] >183 それだとDATA_MEMBERが評価される前に$が評価されてしまうので結局同じことになりませんか? 色々漁ってみたら限界はあるもののいくつか対処法はあるみたいですね. lists.boost.org/MailArchives/boost/msg46364.php からだと template<class T> struct wrap { typedef T type; }; template<class T> struct wrap<void (T)> { typedef T type; }; #define TYPE(x) wrap<void x>::type #define DEP_TYPE(x) typename wrap<void x>::type struct Sample2 { typedef Sample2 _self; BEGIN_JUNK( ZJunkBase, typedef ZTypeList<> _data_member1; ); DATA_MEMBER( 1, TYPE((my_class<char, int>)), x ); END_JUNK(); }; とか.記事本文では指摘されていないですけれど,型がdependent typeか どうかでマクロを使い分ける必要もありますね,これ. ・・・っていうか話題をそらしてしまってすいませんです.
185 名前:181 mailto:sage [05/01/07 00:10:36] >>184 コンパイル通らないですか? 当方、VC++ 2003 しかないので、他のコンパイラだと通らないのだったら正直すまん ただ、VC++ 2003 でも多重にマクロを定義している時は、評価順序によって通らない時もある その時はマクロを調整するでは駄目ですか・・? リンク先のようなやり方もあるとは知りませんでした 参考にさせて頂きます
186 名前:181 mailto:sage [05/01/07 00:38:04] あと、typename に対してですが __if_exists が使えればこういうやり方もあります template< bool >struct ExistsBool {}; template<>struct ExistsBool< true > { enum { _true }; }; #defineTYPEDEF( __Type, __Alias ) \ __if_exists( __template__::_true ){ \ typedef typename __Type __Alias; \ } \ __if_not_exists( __template__::_true ){ \ typedef __Type __Alias; \ } \ template< class _Type > struct Sample7 { typedef ExistsBool< true >__template__; TYPEDEF( _Type::_type, _type ); // 2値判定にも使える __if_exists( ::ExistsBool< _Type::_n == 0 >::_true ){ } }; __template__ をクラスごとに宣言する必要があるのが難点ですが
187 名前:デフォルトの名無しさん mailto:sage [05/01/07 19:48:15] >>184 >それだとDATA_MEMBERが評価される前に$が評価されてしまうので結局同じことになりませんか? 引数展開の前に引数は確定するから、この例では問題ない。 でもこの結果を別のマクロに渡すと結局だめだから、 あまりお勧めはできないが。 # define ID(x) x # define COMMA() , # define DECL_A(type, var) type var # define DECL_B(type, var) ID(type) var DECL_A(std::pair<int COMMA() int>, pa); // ok DECL_B(std::pair<int COMMA() int>, pb); // error: IDの引数過多
188 名前:184 mailto:sage [05/01/07 21:39:12] >186 考えてみた結果enclosing scopeがtemplateかどうかに対する切り分けが 本質的に必要ではないかと思うのでこの方法はあまり使えなさそうです. >187 マクロのargument substitutionについて理解が足りていませんでした. function-like macroがidentityされてから後,replacement-listに対する 置換が実行される前にargumentに含まれるmacro tokenが置換されるんですね. 見た感じやはり184の解法が幾分かbetterでしょうか.
189 名前:181 mailto:sage [05/01/08 00:55:07] これでどうだろう。>>184 と組み合わせてみた。 template<class T> struct wrap{ typedef T type; }; template<class T> struct wrap<void (T)>{ typedef T type; }; #define TYPE(x) wrap<void x>::type template< bool >struct ExistsBool{}; template<>struct ExistsBool< true >{ enum { _true }; }; #defineTYPEDEF( type, alias ) \ __if_exists( __template__::_true ){ typedef typename TYPE((typename type)) alias; } \ __if_not_exists( __template__::_true ){ typedef TYPE((type)) alias; } \ #defineCLASS( __Class ) \ typedef __Classself; \ typedef ExistsBool< false >__template__; \ #defineTEMPLATE( __Class ) \ typedef __Classself; \ typedef ExistsBool< true >__template__; \ #define$,
190 名前:181 mailto:sage [05/01/08 00:55:32] つづき template< class T > struct hara { TEMPLATE( hara ); template< class T > struct horo { TEMPLATE( horo ); TYPEDEF( T::type,type ); }; struct hire : public horo< T > { CLASS( hire ); TYPEDEF( my_class<char $ int>, type2 ); }; TYPEDEF( hire::type, type ); TYPEDEF( hire::type2, type2 ); }; $ を主張するわけではないが、タイプ量が少ないと嬉しいので ところで、誰も Jankyard に触れてくれない orz
191 名前:デフォルトの名無しさん mailto:sage [05/01/08 01:04:10] 誤: typedef __Classself; 正: typedef __Class self; 誤: #define$, 正: #define $ , です。連投すんまそん
192 名前:デフォルトの名無しさん mailto:sage [05/01/09 07:22:01] >ところで、誰も Jankyard に触れてくれない orz ぶっちゃけていうとreflection系ライブラリの提案はすでに色々ありますからね. 自分の知っている範囲だと www.garret.ru/~knizhnik/cppreflection/docs/reflect.html www.arneadams.com/reflection_doku/index.html あたりでしょうか?後プロパティの実装なら www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1615.pdf とか. ついでに__if_existsに関して,名前がするかどうかというコンパイル時の情報で プリプロセッサレベルの処理を行えるというのは確かに強力で魅力的なんですが やはりVC++限定なのがネックでしょうね. 一応クラスのメンバ(型・関数・変数)や非メンバ関数の存在をテストしてその情報を コンパイル時に取得する技法を標準C++の範囲内で実装することは可能なので, それでほとんどの部分は代用できると思います. (というか自分は本質的に__if_existsが必要な状況を思い付けません)
193 名前:181 mailto:sage [05/01/09 09:15:49] >>192 今回提案したのはリフレクション自体ではなく、その辺りをサポートする仕組みだったのだが。 リフレクションも含む、その他タイプリスト生成や、マクロ間での型の受け渡し、 継承関係の中で連番発行など。プロパティはネタです。 __if_exists は本質的に必要ないのには同意します。 ただ、テンプレートの特化の変わりに使えるので __if_exists を使うとシンプルに記述出来ることも少なくありません。 この辺りは好みによるのでしょうね。 VC++限定なのはどうしようもないですが。 いづれにせよ、騒がしているだけのようなので、これで引っ込むことにします。 >一応クラスのメンバ(型・関数・変数)や非メンバ関数の存在をテストしてその情報を >コンパイル時に取得する技法を標準C++の範囲内で実装することは可能なので, >それでほとんどの部分は代用できると思います. 詳細きぼん
194 名前:デフォルトの名無しさん [05/01/09 12:47:08] ここでいいのかしら。ちょっと彷徨い気味ですがどうぞよろしゅう 2つのソート済みvectorの中で共通する項目の数を数えたいのですが set_intersection( (省略) , common_ins) common.size(); で実行しています。これだとvectorの中身が100kとかになった時に速度がちょっとまずいのです。 上記より高速な方法でなにか良案ご存知の方いらっしゃいませんか? ちなみのその後、共通部分から作ったcommonに対する処理は何も行いません(数えたいだけです)
195 名前:デフォルトの名無しさん mailto:sage [05/01/09 12:52:27] vecAとvecBを mergeしてvecCを作りuniqueしてvecA.size()+vecB.size()-vecC.size()
196 名前:デフォルトの名無しさん mailto:sage [05/01/09 12:54:20] set_intersectionもソート済み範囲なのか。なら>>194 の方が遅そうだ。
197 名前:デフォルトの名無しさん mailto:sage [05/01/09 12:59:38] >>195 のがだろ
198 名前:デフォルトの名無しさん mailto:sage [05/01/09 13:00:07] www.google.com/search?num=100&as_qdr=all&as_occt=any&as_dt=i&ie=sjis&oe=sjis&lr=lang_ja&as_q=%83%5c%81%5b%83g%8d%cf%82%dd%83x%83N%83%5e%82%cd%92x%82%a2
199 名前:194 mailto:sage [05/01/09 13:14:44] mergeして差分を考える方法は実行済みなのですが 残念ながら、set_intersectionの方法に比べて倍近く時間がかかってしまったのです う〜ん、これはもう構造的にどうしようもないですかね 割と頻繁に更新されるvectorなので、馬鹿にならないコストなんですが・・・
200 名前:デフォルトの名無しさん mailto:sage [05/01/09 13:29:34] スマートポインタを使ってるならただのポインタに変えてみる。 ただのポインタなら実体に変えてみる。 実体ならポインタに変えてみる。
201 名前:デフォルトの名無しさん mailto:sage [05/01/09 13:33:31] set_intersection の result は OutputIterator なので、 *result = common (or *result++ = common) がカウントアップの動作をするような擬似イテレータを作れば、 コピーのコストを無くすことができそうだ。
202 名前:デフォルトの名無しさん mailto:sage [05/01/09 13:39:05] うっ、そこを触ることになりますか… Iteratorの中身について理解が出来ていないので全くの手探りになりますが、資料ひっくり返して勉強します ありがとうございました
203 名前:デフォルトの名無しさん mailto:sage [05/01/09 14:48:42] 暇つぶしにやってみた。 boost::counting_iterator がそのまま使えるかと思ったけど OutputIterator じゃなかった。 しょうがないから結局ファンクタ書く羽目になった。 #include <cstddef> #include <algorithm> #include "boost/function_output_iterator.hpp" template<typename Incrementable> class increment { Incrementable* m_target; // not reference to make this class Assignable public: increment(Incrementable& target) : m_target(&target) {} template<typename T> void operator () (T const&) { ++*m_target; } }; template<typename InputIterator1, typename InputIterator2> std::size_t count_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { std::size_t result = 0; std::set_intersection(first1, last1, first2, last2 , boost::make_function_output_iterator(increment<std::size_t>(result))); return result; } lambda 使えば、 increment くらい消せるかも。
204 名前:デフォルトの名無しさん mailto:sage [05/01/09 17:29:22] いちおうできた。 #include <cstddef> #include <algorithm> #include "boost/function_output_iterator.hpp" #include "boost/lambda/lambda.hpp" template<typename InputIterator1, typename InputIterator2> std::size_t count_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { std::size_t result = 0; std::set_intersection(first1, last1, first2, last2 , boost::make_function_output_iterator(++boost::lambda::var(result))); return result; } ただ、 lambda のファンクタが Assignable にならないので、 _GLIBCXX_CONCEPT_CHECKS で怒られた。 VCでは /W3 まで大丈夫。
205 名前:デフォルトの名無しさん [05/01/09 19:25:21] template<class T> struct X { void func() {} }; TがクラスAかクラスAのpublic派生クラスの特殊版を定義する場合 X<T>::func()をどのように定義すればよいのでしょうか?
206 名前:デフォルトの名無しさん mailto:sage [05/01/09 23:59:37] >193 具体的な実装の例だとboost/mpl/has_xxx.hppとかが参考になるかと思います. >205 Boost使うなら以下のような感じでですかね? #include <iostream> #include <boost/mpl/if.hpp> #include <boost/type_traits/is_base_and_derived.hpp> struct A{ }; template<class T> struct X{ struct yes_tag{ }; struct no_tag{ }; typedef typename boost::mpl::if_< boost::is_base_and_derived<A, T>, yes_tag, no_tag>::type dispatch_tag; void func_dispatch(yes_tag){std::cout << "derived version" << std::endl;} void func_dispatch(no_tag){std::cout << "non-derived version" << std::endl;} void func(){ func_dispatch(dispatch_tag()); } }; struct Hoge : public A{ }; struct Huga{ }; int main(){ X<Hoge>().func(); X<Huga>().func(); }
207 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:24:10] こういう書き方って動作は保証されるのでしょうか? std::vector<int> test; for ( std::vector<int>:iterator element = test.begin(); element != test.end(); element++ ) { test.erase(element); }
208 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:30:51] ↑おもいっきりぬけてたので修正しました std::vector<int> test; test.push_back(0); test.push_back(1); test.push_back(2); test.push_back(3); test.push_back(4); for ( std::vector<int>:iterator element = test.begin(); element != test.end(); element++ ) { if ( *element == 2 ) { test.erase(element); } }
209 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:35:21] >>208 eraseした時点でイテレータそのものが無効になるよ。
210 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:38:08] ではループしつつ条件に当てはまるイテレータの内容だけ削除するには どのような手段を用いればよいのでしょうか? プールで一端どこかにマークをつけて、ループ終了後該当の物だけeraseとかでしょうか?
211 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:38:33] だから、std::remove()で、値が2の要素をコンテナの後に集めておき、最後に一回だけ eraseするといい。 test.erase(std::remove_if(test.begin(), test.end(), std::bind2nd(std::equal<int>(), 2)), test.end());