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 あたりに。
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());
212 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:38:57] あ、ループがプールに・・orz
213 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:39:57] なるほど、ありがとうございます
214 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:40:36] こういう書き方は最初は戸惑うかもしれないが、慣れるとすごく便利になる。 そのうちこれでも不便になって、必ずboost::bindとかに手を出したくなるから。
215 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:43:26] わかりました。 参考にしてみます。
216 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:43:57] というか、EffectiveSTLを読め。 >>211 のも含めて色々書いてあるから
217 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:50:47] test.erase(std::remove(test.begin(), test.end(), 2), test.end()); でもいいねこの場合。叙述関数あるいは関数オブジェクトの替わりにconstな値を とるだけだから。
218 名前:デフォルトの名無しさん mailto:sage [05/01/10 17:58:23] if ( *element == 2 ) { test.erase(element++); } でOK。
219 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:01:18] >>218 は忘れて。 for ( std::vector<int>:iterator element = test.begin(); element != test.end(); ) { if ( *element == 2 ) { element = test.erase(element); } else ++element; }
220 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:01:28] >test.erase(std::remove_if(test.begin(), test.end(), std::bind2nd(std::equal<int>(), 2)), test.end()); わけがわかりません。 こんなの仕事で使われたら恐怖です。 やめてください。
221 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:02:08] >>217-219 やめてください。 怖いです。
222 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:02:50] >>218 vectorコンテナのeraseはCで言うところのrealloc()に相当する動作を実行する 事もあるんだぞ。でたらめ書くな。
223 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:03:47] >>220 そのくらいのSTL構文も分からないならC++使うのをやめた方がいいよ。
224 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:06:37] >>222 おいおい。 「イテレータは、より小さなインデックスの要素が挿入または削除されたり、再割り当てが 行われて容量が変わるまで有効」だぞ。 規格票をよく読め。おまえこそでたらめ。
225 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:10:44] 規格票でました。 m9(^Д^)プギャー
226 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:12:25] §23.1.2.8当たりだろ。
227 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:13:13] www-6.ibm.com/jp/developerworks/linux/041203/j_l-cpregex.html >言語の機能 であるはずのものが、その言語のユーザーを恐れさせるようになったら、何かを変えるべき時なのです。
228 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:13:59] >>226 それAssociative Container
229 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:15:05] ここは 問題を無闇に複雑にして悦に浸る馬鹿のス靴(なぜか変換できない) ですね。
230 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:19:30] §23.2.4.3当たりだと見た。
231 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:20:25] >>227 >>229 またperlとかrubyの○キ信者ですか?
232 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:23:27] boostが異常なのは認めなければなるまい。 昨今のC++は異常が常態。
233 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:24:29] 確かに異常だが、使っているうちに快感になる。
234 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:24:50] (23.1.1/7)と(23.2.4.3/3)読む限り>219でもOKっぽいですね
235 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:27:46] CommonLispのようなわかりにくさを競い合って悦に浸るのがここの流儀
236 名前:デフォルトの名無しさん mailto:sage [05/01/10 18:28:39] >>234 OKだろ。個人的には俺はあまり書きたくないけど。
237 名前:デフォルトの名無しさん [05/01/11 00:57:13] >>219 引くってのはどうよ。 for(element = test.begin(); element != test.end(); ++it) { if(*element == 2){ test.erase(element--); } } あ、でも element = test.begin(); element--; は大丈夫なのかな。 まぁ、EffectiveSTLを読んでいれば test.erase(remove(),test.end())と書くというのに一票。
238 名前:237 [05/01/11 00:58:59] 訂正。 >>237 ++it => ++element
239 名前:デフォルトの名無しさん mailto:sage [05/01/11 01:06:22] >>237 ダメ
240 名前:デフォルトの名無しさん mailto:sage [05/01/11 14:28:58] for(element = test.begin(); element != test.end(); ++element) if(*element == 2) { element = --test.erase(element); } こんな感じが一番シンプルなところなのかな?
241 名前:デフォルトの名無しさん mailto:sage [05/01/11 15:04:23] removeとeraseの組み合わせが一番シンプル
242 名前:デフォルトの名無しさん mailto:sage [05/01/11 15:59:47] とりあえずremoveとeraseの組み合わせが何でも一番です(^^
243 名前:デフォルトの名無しさん mailto:sage [05/01/11 16:01:18] clearって手もあるよ
244 名前:デフォルトの名無しさん mailto:sage [05/01/11 19:46:02] >>223 プロジェクトって大抵いろんな技術レベルの人がいるから その台詞でばっさりはちょっと抵抗あるなぁ。 一人でやるなら何使ったってOKだけどね。
245 名前:デフォルトの名無しさん mailto:sage [05/01/11 20:32:55] >>244 211はかなり基本だと思うんだけど...
246 名前:デフォルトの名無しさん mailto:sage [05/01/11 20:46:56] あれが解からないって? …ときどき思うんだ。俺、なんで2chなんか見てるんだろう、って。
247 名前:237 [05/01/11 22:30:46] なんか不安になってきたので確認したいのですが vectorのeraseで無効になるのは消した要素以降のイテレータですよね。 だから>>237 と>>240 は結果的に同じことになりますよね? 私が>>237 で心配だったのは 最初の要素でヒットしたとき、 element = test.begin(); --element; ++element; でbegin()に戻るのが規格で保証されてなさそう(多くの実装では戻りそうだけど) というのと 元々のサイズが1のとき、test.erase(test.begin());で全てのイテレータが無効になる ときにバッファを解放してbegin()とend()がNULLを返してくるようになるとend()と 永遠に一致しなそう(VC7のclearがバッファを解放(capacityを0)にしてくれるのに 気づいて以来疑り深くなっています) の二点なんですけど、 そのあたりをふまえて>>239 はダメと言っているんですよね? うーん、remove(や類似のアルゴリズム)を使わないでやるならやはり>>219 なのか。
248 名前:237 [05/01/11 22:34:15] ああ、そうか、後者の不安は>>240 と書くことで払拭されるのか。 スマソ
249 名前:244 mailto:sage [05/01/12 01:12:53] >>245 俺も基本だと思ってるし、これぐらいわかれよって思ってるよ。 でも、それが通用しないのが多人数でしょ?って投げかけ。 …技術と関係なくなるか。消えるよ。スレ汚しすまん。
250 名前:デフォルトの名無しさん mailto:sage [05/01/12 02:17:30] なぜforで回す……わざわざC++使うんだったら、効率にも気を 配らないともったいないよ。 >247 >237 >240の例だと ・ループごとにtest.end()の呼び出しが発生する ・elementを削除するたびにvectorの再パッケージが発生する で遅くなりますな。 あと、>237だと後置インクリメントの一時オブジェクトの生成が 発生してさらに効率が悪くなります。
251 名前:デフォルトの名無しさん mailto:sage [05/01/12 02:18:18] なぜにremoveを使いたくないのかが知りたい
252 名前:250 mailto:sage [05/01/12 02:24:13] 自己フォロー >237>240ともに、はelement==test.begin()のときに *element==2だとアウトですな。 #test.begin()よりも前に移動するから未定義の世界に突入
253 名前:デフォルトの名無しさん mailto:sage [05/01/12 02:48:28] >250 ループごとのtest.end()も後置インクリメントもここでは本質じゃない。
254 名前:デフォルトの名無しさん mailto:sage [05/01/12 02:56:25] >253 ふうん、じゃ、こう言っておこうかな ・郷に入れば郷に従え STLはC++の一部なんだから、それぐらい覚えろ ・こんぐらいできないなら、そもそもC++使うな or こんなこともできないやつをプロジェクトに入れるな 他にもPerlとか色々あるんだから、わざわざC++を使う必要ないよね。
255 名前:デフォルトの名無しさん mailto:sage [05/01/12 07:36:48] list に追加されている remove(),remove_if() 見習って、 template<class Container> void remove(Container&, typename Container::value_type const&) template<class Container, class Predicate> void remove_if(Container&, Predicate p); のような関数を作れば、双方文句はなかろう。
256 名前:255 mailto:sage [05/01/12 07:50:40] s/Container/Sequence/ remove() の意味が混乱を招きやすいという認識はSGIのドキュメントにも記載されている。 「慣用句だ」と言って押し切るよりは、むしろまともな認識だと思う。 www.sgi.com/tech/stl/remove_if.html#1 これをそのままソースに書いてしまうと言うのは、 例えば定数除算をシフトで書いてしまうのと同等の誤りであると思う。
257 名前:デフォルトの名無しさん [05/01/12 07:51:49] forで回すからうっかり>>218 とか>>237 とか>>240 とかいう問題のあるコードを書いて しまうんだよ。 だったらおとなしくremoveを使えと。 まぁ、色々書き方があってその中から適切な物を状況に応じて選ぶのがプログラムの 醍醐味ではあるけど。
258 名前:デフォルトの名無しさん mailto:sage [05/01/12 08:53:47] >なぜにremoveを使いたくないのかが知りたい 叙述関数やoperator==とかにコードが分散するのがイヤ ループが内包されるのがイヤ ループを制御下に置いておきたい ブレイクポイントが設定しやすいよ 削除以外の用途にループが流用できるよ てゆうかぶっちゃけremove_copy中でやってること、あれはありえないでしょ それを言ったらvectorでeraseすること自体ありえないかw
259 名前:デフォルトの名無しさん mailto:sage [05/01/12 09:59:55] >ループが内包されるのがイヤ ループを制御下に置いておきたい ループを明示的に書くより効率が良くなる可能性があるし、 コードの見通しも良くなる
260 名前:デフォルトの名無しさん [05/01/12 10:06:05] >>254 「理想郷」との差でしかモノを語れない 頭でっかちの引き籠もりはレスしなくていいです ;-)
261 名前:デフォルトの名無しさん mailto:sage [05/01/12 10:32:21] >260 それ、オレじゃない。人違いだ
262 名前:デフォルトの名無しさん [05/01/12 10:48:33] >260 IDくらい見ろ、ボケ!
263 名前:デフォルトの名無しさん mailto:sage [05/01/12 11:10:58] >>262 この板ID無いんだって気付よ!
264 名前:デフォルトの名無しさん mailto:sage [05/01/12 11:21:54] お前さんたちなんか楽しそうだね。
265 名前:デフォルトの名無しさん mailto:sage [05/01/12 11:42:25] IDの見方知らない香具師ってまだいたんだね
266 名前:デフォルトの名無しさん mailto:sage [05/01/12 12:13:29] はっきりいってvectorに限らず配列っぽいデータ構造を使っている時に removeみたいなアルゴリズムを適用したくなることってあるか? 無理して適用しておもしろいことがあるようなものでもないと思うのだけど… 何か見落としている革新的な理由でもあったりするのだろうか?
267 名前:デフォルトの名無しさん mailto:sage [05/01/12 23:55:01] > removeみたいなアルゴリズムを適用したくなることってあるか? 配列から複数の要素を一度に取り除きたいときだな。
268 名前:デフォルトの名無しさん mailto:sage [05/01/13 00:11:28] 簡単 let remove x num = snd (List.partition (fun a -> a=x) num);;
269 名前:デフォルトの名無しさん [05/01/14 14:04:12] >>268 配列っぽくないデータ構造。
270 名前:デフォルトの名無しさん [05/01/15 01:33:25] >>267 そそ、端からeraseしてると効率悪いし、 効率的な処理にしようとすると意外に面倒。
271 名前:デフォルトの名無しさん mailto:sage [05/01/17 09:41:54 ] 俺も小さくて、しかもあまり使わないような関数を分散させるのが嫌いなんだけど、 「リファクタリング」を読むと、一行処理すら場合によっては関数にすることを推奨してるんだよな。 しっかりした関数名をつけることによって可読性が高まるって話なんだけど、 必ずしもそうとは思えないのは、英語圏ネイティブじゃないせいかね。 と、templateスレに書き込もうとしたのだけど、主旨に合わないのでこっちに投棄
272 名前:デフォルトの名無しさん mailto:sage [05/01/17 09:43:01 ] C++スレに書くつもりが… もうどうでもいいや
273 名前:デフォルトの名無しさん mailto:sage [05/01/17 13:41:34 ] リファ〜に書いてあるのは関数じゃなくてメソッドのことでは 何の分類もしない単独の関数増やしてくのはあんま良いとは思えないが メソッドの場合インターフェース抽出とか階層整理とかで意味がある
274 名前:272 mailto:sage [05/01/17 17:58:06 ] >>273 失礼、つい関数と呼んじまう。 インターフェース抽出や階層整理は、それ自体をメインにして行うべきな気がするんだよねぇ。 それどころかそれ以前で、非道い話だが「たくさんの、たった数行のメソッド」ってだけで、嫌悪感を感じてしまう。 いずれにせよスレ違い申し訳ない。
275 名前:デフォルトの名無しさん mailto:sage [05/01/18 00:41:35 ] >>273 そんな区別ないだろ。 少なくともC++ではthisポインタの有無しか違いはないわけで、 それが関数分けの基準に影響するとは思えない。
276 名前:デフォルトの名無しさん mailto:sage [05/01/18 01:35:22 ] 時々272のような人いるよね。 読むときあっちこっちの関数みないといけないから、とか言って。 このヘタレが
277 名前:デフォルトの名無しさん mailto:sage [05/01/18 01:45:39 ] そもそも行数とか関係ないだろ
278 名前:デフォルトの名無しさん mailto:sage [05/01/18 02:41:33 ] >275 その他にも可視性とアクセス範囲に違いがあるわけで……
279 名前:デフォルトの名無しさん mailto:sage [05/01/18 08:17:20 ] >>278 そうだな。 それらが要るならクラス作ってメンバ関数を作ればいいし、 要らないならフリー関数にしてもいい。 どう整理するかどうかが違うだけで、 処理に名前をつけてまとめたほうがよいかどうかの基準には関係ない。 複数のフリー関数を作った後に、さらに それらをまとめてクラスを作ればよいことに気付くことも考えられる。 思い立ったらさっさと名前付けてまとめれ。 渋る意味がわからん。
280 名前:272 mailto:sage [05/01/18 08:20:53 ] ちとスレ違い悪いんでこっちでレス pc5.2ch.net/test/read.cgi/tech/1099112338/41
281 名前:デフォルトの名無しさん mailto:sage [05/01/21 18:18:02 ] お聞きしたいのですが、 下記(次レス)のコードがVC7.1でコンパイルできませぬ。 どこがいけないのでしょうか… 色々実験してみた結果 ・UINT を int にすると通る。 ・UINT を std::size_t にしてもダメ。 ・typename T を削除して、 boost::array の T を int とかにすると通る。 ・boost:array の nSize を適当な数値で直打ちすると通る。 ・bcc5.5.1 では普通に通る。
282 名前:281 [05/01/21 18:18:34 ] #include <boost/array.hpp> typedef unsigned int UINT; template<typename T, UINT nSize> class A { typedef typename boost::array<T, nSize> tObjects; typedef typename tObjects::iterator tObjectsIt; tObjects m_cObjects; public: tObjectsIt Func(); }; // ↓C2244:関数の定義を既存の宣言と合致させることができませんでした。 template<typename T, UINT nSize> inline typename A<T, nSize>::tObjectsIt A<T, nSize>::Func() { return m_cObjects.begin(); }
283 名前:デフォルトの名無しさん [05/01/21 20:49:28 ] >>281 手元にVC7.1もboostもないし、よくわからんけど、 コンパイラがバグってることはよくあるからw
284 名前:デフォルトの名無しさん mailto:sage [05/01/21 20:57:34 ] >>282 g++(3.3.3)ではなんの警告もエラーもなく通るのぅ……
285 名前:デフォルトの名無しさん mailto:sage [05/01/21 21:31:52 ] >>282 戻り値を素直に typename boost::array<T, nSize>::iterator とすると通りますね。
286 名前:デフォルトの名無しさん mailto:sage [05/01/22 00:57:24 ] typedefがprivateなのにinlineなのがいけないんじゃないのか? と試してもないのに言ってみる
287 名前:281 mailto:sage [05/01/22 11:00:38 ] やはり、コンパイラが悪い方向なんですか… orz なお、>>286 を参考に、 すべてのメンバをpublic にしてみてもコンパイルが通りませんでした。 しょうがないので、現状では ・class内に直書き ・>>285 の方法 の2点で回避したいと思います。 どうもありがとうございました。
288 名前:デフォルトの名無しさん mailto:sage [05/01/22 11:27:55 ] いまだにちゃんと動かないコンパイラ多いのかよ おまえらC++信用できますか?
289 名前:デフォルトの名無しさん mailto:sage [05/01/22 11:28:34 ] C++なら信用できるよ。
290 名前:デフォルトの名無しさん mailto:sage [05/01/22 15:39:27 ] >>282 vc8 でもダメっぽい
291 名前:デフォルトの名無しさん [05/01/23 15:44:13 ] boost::bindはstd::bind2ndとかより実行速度が落ちるって本当ですか?
292 名前:デフォルトの名無しさん mailto:sage [05/01/23 16:18:47 ] >>291 ためして、みなさいって。
293 名前:デフォルトの名無しさん mailto:sage [05/01/23 16:20:48 ] using句が,による複数引数を受け付けないのは何故ですか? using A::AA, A::AB, A::AC; のように出来たら便利だと思うのですが?
294 名前:デフォルトの名無しさん mailto:sage [05/01/23 17:06:31 ] 本スレの次スレ 【標準C++】C++相談室 part39【STL含む】 pc5.2ch.net/test/read.cgi/tech/1106466303/
295 名前:デフォルトの名無しさん mailto:sage [05/01/23 17:51:32 ] >>293 そんなんオレらに聞かれても困るよ
296 名前:デフォルトの名無しさん mailto:sage [05/01/23 17:57:05 ] >>293 プリプロセッサマクロを書くとか? あんまり便利とも思えないけど
297 名前:デフォルトの名無しさん [05/01/23 22:42:53 ] boost(かSTL)に、次のような関数テンプレートって含まれていませんか? template<typename T> inline void assign(T& lhs, const T& rhs) { lhs = rhs; } 次のような感じで、setterを用意していないメンバ変数(m_is_foo)を変更する関数オブジェクトを作るのに使いたいのです。標準であるならそっちを使いたいなと思いまして。 hoge(boost::bind(assign<bool>, boost::ref(m_is_foo), true));
298 名前:デフォルトの名無しさん mailto:sage [05/01/23 23:01:05 ] >>297 試してないけど、 hoge(boost::lambda::var(m_is_foo) = true) じゃだめ?
299 名前:297 mailto:sage [05/01/23 23:16:36 ] >>298 > 試してないけど、 hoge(boost::lambda::var(m_is_foo) = true) じゃだめ? いけました。サンクスです。 うーん、lambdaか…。主観ですが実戦投入はちょっと怖いんですよね。
300 名前:デフォルトの名無しさん mailto:sage [05/02/07 09:18:51 ] ふぇ〜い Boostを最新リリースにしたら@VC6 _bvector.hでコンパイラが内部エラー起こしてビルドできない Releaseビルドなら通った コンパイラもしょっちゅう固まるし やっぱ テンプレートをプリコンパイルヘッダにしたのが悪いのかな ・・
301 名前:デフォルトの名無しさん mailto:sage [05/02/07 09:23:19 ] 日記はMeadowにでm(ry
302 名前:デフォルトの名無しさん mailto:sage [05/02/07 09:28:51 ] >>300 ヘッダのインクルード順序を変えてみれ。 自分は面倒なので#ifとか使ってインクルード順序をすぐに変えられるようにしてる。 例: #if 0 //ここを1にしたり0にしたりする。 #include <boost/regex.hpp> #include <algorithm> #else #include <algorithm> #include <boost/regex.hpp> #endif
303 名前:デフォルトの名無しさん mailto:sage [05/02/07 14:42:53 ] Meta-Programming 専用のスレってない?
304 名前:デフォルトの名無しさん mailto:sage [05/02/07 17:41:03 ] あったけど、ここに統合。
305 名前:デフォルトの名無しさん [05/02/11 13:36:27 ] テンプレートを使ったクラスでundefined referenceがでます。 ソースは次のようなものです。プリプロセッサは省略してあります。 //temptest.h template<class T> class temptest{ public: temptest(); }; //temptest.cpp template<class T> temptest<T>::temptest(){} //main.cpp int main(){ temptest<int> t; return 0; } gccでは "undefined reference to `temptest<int>::temptest(void)" VisualC++6では "public: __thiscall temptest<int>::temptest<int>(void)は未解決です" というエラーです。 ちなみに定義をインラインにしたらうまくできました。 どなたか解決方法を教えてください。
306 名前:デフォルトの名無しさん mailto:sage [05/02/11 13:40:12 ] >>305 templateの定義はヘッダに書かないとダメ、ということになってます。
307 名前:304 mailto:sage [05/02/11 13:50:47 ] そんな決まりがあったんですか。 でもSTLのインクルードファイルを見たところ宣言だけのようですが、 STLは特別なんでしょうか。
308 名前:デフォルトの名無しさん mailto:sage [05/02/11 13:52:15 ] STLもヘッダの下のほうに書いてあるんじゃねーの
309 名前:デフォルトの名無しさん mailto:sage [05/02/11 13:52:42 ] STLも例外ではないよ クラステンプレートに実体がなくてもその後ろにクラスメンバのテンプレートの実体が定義されてるはず
310 名前:デフォルトの名無しさん mailto:sage [05/02/11 14:13:29 ] stlportだとcppをヘッダからincludeしてたとおもう
311 名前:デフォルトの名無しさん mailto:sage [05/02/11 14:44:21 ] ヘッダからcppをインクルード・・・萌えるな。
312 名前:デフォルトの名無しさん mailto:sage [05/02/11 15:04:53 ] >>307 temptest.cpp コンパイル時には class T が何だか解らないので コンストラクタは生成されない ↓ main.cpp コンパイル時には temptest<int> のコンストラクタが どこかにあるものとしてコンパイル ↓ リンクしてみたら、どこにもいない 明示的にインスタンス化するよろし。 //temptest.cpp template class temptest<int>;
313 名前:デフォルトの名無しさん mailto:sage [05/02/11 16:01:01 ] exportキーワードをまともに実装した処理系はComeau C++だけでしょ。
314 名前:デフォルトの名無しさん mailto:sage [05/02/11 19:41:42 ] もう諦めてexportを標準から外した方が良いんじゃないかとさえ思ったり. 現状,exportによる利得というのがほとんど無いみたいですし.
315 名前:デフォルトの名無しさん mailto:sage [05/02/11 21:11:04 ] つーか既に実装しなくていいよもう、ってことになったんじゃなかったか?
316 名前:デフォルトの名無しさん mailto:sage [05/02/11 21:50:10 ] >315 ソースきぼんぬ. export周りは泣きそうなほどグダグダみたいですし,さもありなんですけど.
317 名前:デフォルトの名無しさん mailto:sage [05/02/11 22:10:19 ] それがC++クオリティ
318 名前:デフォルトの名無しさん mailto:sage [05/02/12 06:49:19 ] >>316 D&E日本語版読んでみ。 exportは未だに実装してないといけない規格になっている。
319 名前:デフォルトの名無しさん mailto:sage [05/02/12 19:42:14 ] exportって何?
320 名前:デフォルトの名無しさん mailto:sage [05/02/12 19:42:57 ] るby
321 名前:デフォルトの名無しさん mailto:sage [05/02/16 10:47:32 ] shared_ptrとかintrusive_ptrのリファレンスカウント操作って 引数で値渡しすると呼び出しのたびに操作しますよね。 最適化によるコード削減を阻害しないでしょうか? 特にテンプレートを展開したもののコードがどうなるかが気になります。
322 名前:デフォルトの名無しさん mailto:sage [05/02/16 11:26:01 ] >>321 適材適所で。 それからテンプレートの勉強もね。
323 名前:デフォルトの名無しさん mailto:sage [05/02/16 11:38:00 ] >>322 要するにオーバーヘッドはかかるというお答えという理解でよろしい? intrusive_ptrの参照を渡せばいいんですけど、ポインタの置き換えに使うつもり でいるといまひとつ面倒というか泥くさいというか。 あと、これらのコンテナをfor_eachなどで処理するときのbind(+lambda)で、 _1 と書くだけじゃdeductionしてくれず、bind(&HogePtr::get, _1) のようにしないといけないのが面倒で、 これを何とか自動でやってくれるようにする方法はありませんか。 HogePtrという派生クラスを作ってポインタから暗黙的にキャストさせると 一番簡単にコンパイラを黙らせられるんですが、今度はコンテナを処理するときに 毎回HogePtrを作って比較するというコードを出してくるようになるので、 なるべく派生はさせずに済ませたい。
324 名前:デフォルトの名無しさん mailto:sage [05/02/16 20:11:57 ] 参照カウンタによるオーバーヘッドが許せないのなら、 shared_ptr系は精神衛生上使わないほうがいいと思う。
325 名前:デフォルトの名無しさん mailto:sage [05/02/17 00:41:46 ] >>323 bind の件は既に修正済みのはず。
326 名前:デフォルトの名無しさん mailto:sage [05/02/17 14:17:53 ] >>323 恐ろしいことだが君のようなハッカーには それらはもうレガシーだ。boostなのにね。 sandboxにModern C++ Designのを移植した policy_ptrというのがあるので見るべき これはなかなか強烈だよ
327 名前:デフォルトの名無しさん mailto:sage [05/02/18 02:14:48 ] >>326 お前は独逸の詩人かよ!?
328 名前:デフォルトの名無しさん [05/02/18 12:12:10 ] >>326 ポリシーベースの派、前に検討して却下してshared_ptr達が採用されたのに なんで今更?
329 名前:デフォルトの名無しさん mailto:sage [05/02/18 20:40:47 ] >328 その議論読んでみたいんですがどこにありますか? policy_ptrは「shared_ptrは重い」といった主張を持つユーザに対する 選択肢の一つとして提供されるのだと思いますよ. そもそもpolicy_ptrはshared_ptrなどの既存のスマートポインタに取って代わるものではなく, むしろそれらと相補関係にあって共存するべきものですし. なのでshared_ptrを"legacy"と表現するのは恐らく適切ではないです. ここら辺のもう少し詳しい議論は以下のスレッドや policy_ptrのドキュメントのFAQあたりが参考になると思います. thread.gmane.org/gmane.comp.lib.boost.devel/116983
330 名前:デフォルトの名無しさん mailto:sage [05/02/18 21:19:44 ] 似たような*_ptrばっか増やして、 馬鹿じゃないの? ふざけてるの?
331 名前:328 mailto:sage [05/02/18 21:23:27 ] >>329 boost.cppll.jp/HEAD/libs/smart_ptr/shared_ptr.htm#FAQ の2番目を。
332 名前:デフォルトの名無しさん mailto:sage [05/02/18 23:38:55 ] >>330 C++ ってそういうもんだよ。人によって用途も違えば、実行環境のリッチさも 天と地ほど違うので。
333 名前:デフォルトの名無しさん mailto:sage [05/02/22 15:00:52 ] 新規にクラスを作るならば、COM のように侵入型の参照ポインタにして、 intrusive_ptr で管理するとか
334 名前:デフォルトの名無しさん mailto:sage [05/02/22 17:27:12 ] STLかboostあたりに、ある条件を満たすものをoutput_iteratorにコピー するような関数はないでしょうか? boost::mplにcopy_ifというそれらしい名前のがあるんですが、 使い方がさっぱりわからない……
335 名前:デフォルトの名無しさん mailto:sage [05/02/22 17:40:29 ] なぜか std に copy_if ないんだよね・・・ boost::filter_iterator と std::copy でなんとか汁
336 名前:デフォルトの名無しさん mailto:sage [05/02/22 17:43:19 ] std::remove_copy_if(first, last, std::not1(pred));
337 名前:336 mailto:sage [05/02/22 17:43:58 ] ごめん。 std::remove_copy_if(first, last, out, std::not1(pred); だ。
338 名前:デフォルトの名無しさん mailto:sage [05/02/22 18:06:02 ] 今回は元のコンテナを変更したくないのでremove_copy_ifは使えなさそうです。 結局自分で書きました。 自分でforループを書くと頭悪くなったように感じるので、 これくらいstdに入れておいてほしいものです……。 template <class InputIterator, class UnaryFunction, class OutputIterator> void copy_if(InputIterator begin, InputIterator end, OutputIterator result, UnaryFunction pred) { for ( ; begin != end; ++begin) if (pred(*begin)) { *result = *begin; ++result; } } g++のヘッダを見るとconcept checkとやらを入れたほうがいいらしいのですが、 何を使えばいいのかよくわからんです。boostに道具があるんでしょうか。 remove_copy_ifも説明がよくわからんのですよね。 削除するのに大きさが変わらないってどういうこと?
339 名前:デフォルトの名無しさん mailto:sage [05/02/22 18:06:58 ] >>338 remove_copy_ifは入力シーケンスを変更しないよ。
340 名前:デフォルトの名無しさん mailto:sage [05/02/22 18:17:58 ] >>338 return result;
341 名前:一つ賢くなった! mailto:sage [05/02/22 18:32:43 ] >>339 おお、本当だ。コードを見るとほぼそっくりではないですか。 今までremove_copy_ifは元のを破壊的に変更しつつ、削除したものを コピーするのだと思っておりました。 名前がミスリーディングだと思うのです……。 >>340 忘れてました。というか気にしてなかったのですが、返すべきですね。
342 名前:デフォルトの名無しさん mailto:sage [05/02/22 19:24:56 ] struct NURUPO { template<typename T> operator T*() { return 0; } }; int ILoveNurupo() { NURUPO mynurupo; return (int)mynurupo[0]; } vc7.1とgcc3.3にガッ
343 名前:デフォルトの名無しさん mailto:sage [05/02/22 21:10:19 ] なんか違わないか?
344 名前:デフォルトの名無しさん mailto:sage [05/02/23 01:38:28 ] >>338 STLPortには入ってるよ。
345 名前:デフォルトの名無しさん mailto:sage [05/02/24 14:00:35 ] テンプレートの特殊化ってどこに書きますか? 以下のように特殊化する型の定義と一緒に書くと、 * primary.h #include <iostream> template <class T> inline void foo(const T&) { std::cout << "primary\n"; } --- * specialized.h #include "primary.h" struct bar {}; template <> inline void foo(const bar&) { std::cout << "specialized\n"; } --- * troublesome.h struct bar; bar& get_bar();
346 名前:345 mailto:sage [05/02/24 14:01:58 ] * troublesome.cpp #include "specialized.h" bar& get_bar() { static bar b; return b; } void trouble1() { foo(get_bar()); // #1 } --- * main.cpp #include "primary.h" #include "specialized.h" // #2 #include "troublesome.h" int main() { foo(get_bar()); return 0; } --- #1 と #2 をコメントアウトしたりしなかったりで実行結果が変化します。 具体的には #1 と #2 の両方をコメントアウトした場合 primary が出力されます。 かといって、極端な話 STL のヘッダファイルに書き足すわけにもいけませんし・・・。
347 名前:デフォルトの名無しさん mailto:sage [05/02/25 00:39:40 ] >>345 ttp://www.kuzbass.ru/docs/isocpp/template.html#temp.expl.spec 14.7.3 -6- および -7- で、 使う場所より前に特殊化は宣言されていないといけない、 というルールは書いてあるが、コンパイラによるチェックは不要ということになっている。 あげくに規格中に「宣言の位置には気をつけろ」と書かれている。 primary.h の foo<T> の中でダミーでいいから sizoef(T) を使って、 不完全型ではインスタンス化できないようにしておけば、 いちおうエラーにすることができると思う。
348 名前:デフォルトの名無しさん mailto:sage [05/02/28 11:44:49 ] template<class T> class A { public: void hoge() { } void foo() { } // 他にいろいろなメンバがある }; というクラステンプレートがあって、プログラム中でA<T>::hogeだけどこからも使われなかったとき A<T>::hogeのコードは生成されるのでしょうか?
349 名前:デフォルトの名無しさん mailto:sage [05/02/28 12:01:34 ] >>348 されない。だから定義しなくても大丈夫。
350 名前:デフォルトの名無しさん mailto:sage [05/02/28 19:22:11 ] >>348 処理系依存
351 名前:デフォルトの名無しさん mailto:sage [05/02/28 21:47:50 ] >>350 ほんと?
352 名前:デフォルトの名無しさん mailto:sage [05/02/28 22:10:33 ] 一応標準としてはAの暗黙のインスタンス化ではhogeはインスタンス化されません.(14.7.1/1) ちなみにAの明示的インスタンス化の際にはhogeのインスタンス化が伴います.(14.7.2/7)
353 名前:デフォルトの名無しさん mailto:sage [05/02/28 22:10:41 ] >350は狼少年
354 名前:デフォルトの名無しさん mailto:sage [05/03/01 22:32:51 ] >>348 Modarn C++ Designの1.8に、生成されないことを前提にした技法があったな確か。 シンタックス・チェックだけは、実装によっては行われるんだったっけか。
355 名前:デフォルトの名無しさん mailto:sage [05/03/02 01:29:19 ] Modern ね
356 名前:デフォルトの名無しさん mailto:sage [05/03/02 12:31:04 ] スマソ
357 名前:デフォルトの名無しさん mailto:sage [05/03/08 02:55:11 ] AdobeのASLもここでいいんかな?
358 名前:デフォルトの名無しさん mailto:sage [05/03/08 10:23:35 ] 使われているプログラミング技法を語るならここかな あるいはBoostスレか
359 名前:デフォルトの名無しさん mailto:age [05/03/09 18:17:53 ] 以下のコードで complex を set に入れようとしたところ、 「stl_function.h:197: error: no match for 'operator<' in '__x < __y'」 とか言われてしまうのですが (g++ 3.3.3)、原因が分かりません。 何がおかしいのでしょうか。 #include <complex> #include <set> using namespace std; bool operator<(const complex<int> &a, const complex<int> &b) { return real(a) < real(b) || (real(a) == real(b) && imag(a) < imag(b)); } int main() { set<complex<int> > s; s.insert(complex<int>(1, 2)); return 0; }
360 名前:デフォルトの名無しさん mailto:sage [05/03/09 18:39:00 ] >>359 <set>の中からそのoperator<()が見えていない。しかしoperator<()を #includeよりも前に持ってくると今度はcomplexが定義されていない。 しかしstd名前空間内部のものを先行宣言することは許されていない。 自分で関数オブジェクトを定義するしかない。
361 名前:デフォルトの名無しさん mailto:sage [05/03/09 18:40:16 ] namespace std { bool operator<(const complex<int> &a, const complex<int> &b) { return real(a) < real(b) || (real(a) == real(b) && imag(a) < imag(b)); } } で通ったけど、これってやっていいことだっけ……?
362 名前:デフォルトの名無しさん mailto:sage [05/03/09 18:56:02 ] >>360 > <set>の中からそのoperator<()が見えていない。 これは関係ない。どうせグローバルのoperator<は使われない。
363 名前:デフォルトの名無しさん mailto:sage [05/03/09 19:00:21 ] >>361 結論:ダメ 宣言や定義をstd名前空間に加えてはならない。今回の場合、struct std::less<>の特殊化も考えられるが、後述の規定によりuser-definedな名前で 特殊化しない限りundefined behaviorとなる。 17.4.3.1 Reserved names -1 It is undefined for a C++ program to add declarations or definitions to namespace std or namespaces within namespace std unless otherwise specified. A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined name of external linkage and unless unless the specialization meets the standard library requirements for the original template.
364 名前:デフォルトの名無しさん mailto:sage [05/03/09 19:17:37 ] >>362 #include <set> using namespace std; struct hoge{int x;}; bool operator<(const hoge& a, const hoge& b){return a.x < b.x;} int main(){ set<hoge> s; s.insert(hoge()); return 0; } これ通らない?
365 名前:デフォルトの名無しさん mailto:sage [05/03/09 21:08:49 ] >364 それはhogeとoperator<が同じ名前空間(グローバル)で定義されているので通りますよ. std::complexを引数とする呼び出しからoperator<が見えるためには operator<がstd名前空間で定義されていないといけないです. でもそのような定義をstd名前空間に追加することは許されないので(>363), 自分で関数オブジェクトを書いて(>360)それをsetのテンプレート引数に与えるしかないです.
366 名前:デフォルトの名無しさん mailto:sage [05/03/09 21:12:46 ] で、結局こう、と。 #include <complex> #include <set> using namespace std; template <typename T> struct complex_less: binary_function<complex<T>, complex<T>, bool> { bool operator() (const complex<T>& a, const complex<T>& b) { return real(a) < real(b) || (real(a) == real(b) && imag(a) < imag(b)); } }; int main () { set< complex<int>, complex_less<int> > s; s.insert(complex<int>(1, 2)); return 0; }
367 名前:359 mailto:sage [05/03/09 21:25:39 ] >>360-366 皆さんありがとうございます。よく分かりました。 ちゃんと勉強しないとダメだなぁ〜 orz
368 名前:デフォルトの名無しさん mailto:sage [05/03/09 21:55:23 ] string とか pair が std 名前空間に operator < を定義しているから ADL のせいで operator < を std 名前空間の外に探しに行かないという認識であってますか?
369 名前:デフォルトの名無しさん mailto:sage [05/03/09 22:09:23 ] ↑俺には断言できん ↓あってるのか?
370 名前:デフォルトの名無しさん mailto:sage [05/03/09 22:11:50 ] あってる。
371 名前:369 mailto:sage [05/03/09 23:24:46 ] >>368 あってるぞ。 よし、俺ツーポイントゲット。
372 名前:デフォルトの名無しさん mailto:sage [05/03/10 04:08:30 ] その為に less がテンプレート引数になってるんではないのか。 …と、こないだ初めて map で less を使った俺が言いました。
373 名前:デフォルトの名無しさん mailto:sage [05/03/11 02:09:30 ] 練習で push_back_if なるものを書いてみたのですが 駄目だしお願いします。 template <typename IIte, typename Container, typename Pred> void push_back_if(IIte b, IIte e, Container &c, const Pred p) { for(;b!=e;b++) { if(p(*b)) c.push_back(*b); } } insert_if とか copy_if ってないんですか? あったら便利だと思うのですが・・・。
374 名前:デフォルトの名無しさん mailto:sage [05/03/11 02:24:34 ] copy_ifはある。あとはback_inserterを組み合わせて使えばよし。
375 名前:デフォルトの名無しさん mailto:sage [05/03/11 02:27:17 ] > copy_ifはある。 ウソだった。標準ではない。すまん。
376 名前:デフォルトの名無しさん mailto:sage [05/03/11 02:36:13 ] >>373 残念ながらcopy_ifは標準にはない。どっかに作っておいたら? //copy_if template <typename InputIterator, typename OutputIterator, typename Predicate> inline OutputIterator copy_if(InputIterator begin, InputIterator end, OutputIterator destBegin, Predicate p) { while (begin != end) { if (p(*begin)) *destBegin = *begin; ++destBegin; ++begin; } return destBegin; }
377 名前:デフォルトの名無しさん mailto:sage [05/03/11 16:52:41 ] >>373 > for(;b!=e;b++) ++bにしたほうがいい。
378 名前:デフォルトの名無しさん mailto:sage [05/03/11 19:43:05 ] >377 また荒れるようなことを
379 名前:デフォルトの名無しさん mailto:sage [05/03/11 20:28:43 ] いやいや荒れるまでもなく当たり前の事ですよ
380 名前:373 mailto:sage [05/03/11 21:26:10 ] >>374-379 レスが遅くなってすいません。参考にします。
381 名前:デフォルトの名無しさん mailto:sage [05/03/13 00:46:27 ] 荒れてもいいから理由を教えろ
382 名前:デフォルトの名無しさん mailto:sage [05/03/13 01:27:48 ] >>381 後置インクリメントだと、一時オブジェクトが必要になるから。 POD型の場合でもレジスタを余計に必要としたりね。 #それが理由で後置インクリメントを持たないクラスも作ることも多いし。
383 名前:デフォルトの名無しさん mailto:sage [05/03/13 01:32:28 ] C++より++C
384 名前:デフォルトの名無しさん mailto:sage [05/03/13 01:50:07 ] > POD型の場合でもレジスタを余計に必要としたりね。 は?
385 名前:デフォルトの名無しさん [05/03/13 03:26:57 ] 今 typeof が使えるコンパイラって g++, icc の他にどんなのがある? typeofなんてぶっちゃけ template つかってないと殆ど使わんだろうしここでいいよね。
386 名前:デフォルトの名無しさん mailto:sage [05/03/13 09:54:26 ] RTTIとテンプレートはあまり関係ないだろうと思いつつ、 ほとんどのメジャーなコンパイラは扱えますよ。
387 名前:デフォルトの名無しさん mailto:sage [05/03/13 09:57:05 ] typeidじゃないよ。
388 名前:デフォルトの名無しさん mailto:sage [05/03/13 12:31:23 ] メジャーじゃないコンパイラは"ほとんど"に含まれない言葉のトリック
389 名前:デフォルトの名無しさん mailto:sage [05/03/13 13:47:16 ] そういうもんだいではない
390 名前:デフォルトの名無しさん mailto:sage [05/03/13 17:59:47 ] #define FOR_EACH(RANGE, ITERATOR) \\ for(boost::range_iterator::< typeof(RANGE) >::type ITERATOR \\ = boost::begin(RANGE); \\ ITERATOR != boost::end(RANGE); \\ ++ITERATOR) int a[3] = {1, 2, 3}; FOR_EACH(a, it){ cout << *it << endl; }
391 名前:デフォルトの名無しさん mailto:sage [05/03/13 18:00:22 ] struct plus { template<class LHS, class RHS> typeof(l + r) operator()(LHS const &lhs, RHS const &rhs) const{ return lhs + rhs; } private: LHS l; RHS r; };
392 名前:デフォルトの名無しさん mailto:sage [05/03/13 18:15:58 ] 391間違えました.スレ汚してすいません template<LHS, RHS> struct plus_result{ typedef typeof(l + r) type; private: LHS l; RHS r; }; struct plus { template<class LHS, class RHS> typename plus_result<LHS, RHS>::type operator()( LHS const &lhs, RHS const &rhs) const { return lhs + rhs; } };
393 名前:デフォルトの名無しさん mailto:sage [05/03/13 18:17:47 ] typeof って何で標準に入る予定ないの?
394 名前:デフォルトの名無しさん mailto:sage [05/03/13 18:21:14 ] 最初からplus_resultのとこにtypeofを書けばいいような?
395 名前:デフォルトの名無しさん mailto:sage [05/03/13 20:16:10 ] >>393 そんなこと誰が言ったんだ?
396 名前:デフォルトの名無しさん mailto:sage [05/03/13 22:50:55 ] 条件Aに適合する場合にBを適用するという意味で apply_if を書いてみたのですが、駄目だしをお願いします。 template <typename IIte, typename CheckPred, typename ApplyPred> void apply_if(IIte begin, IIte end, CheckPred check, ApplyPred apply) { for(;begin!=end;++begin) { if(check(*begin)) apply(*begin); } }
397 名前:デフォルトの名無しさん mailto:sage [05/03/13 23:18:26 ] >>396 じゃ遠慮なく。 ・名前の省略するな。(×IIte → ○InputIterator) ・Pred は predicate(述語) の略なので、 bool を返す関数以外には使うな。(×ApplyPred → ○UnaryFunction) ・*begin が繰り返されているのは良くない。 ・std::for_each() に倣って UnaryFunction を戻り値としたほうがいいかもしれない。
398 名前:デフォルトの名無しさん mailto:sage [05/03/14 00:29:28 ] >>397 細かいことを言えば、 InputIterator に apply はまずい。 InputOutputIterator じゃ長いけど。
399 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:03:01 ] とりあえず試しに Visual C++ Toolkit 2003 を使ってみたけど、 typeof() は使えない模様。__typeof とかなんかあったりするのかな?
400 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:06:34 ] >>398 イテレータのコンセプトを表すという意味で InputOutputIterator はありえない。 出力も兼ねると言うことなら、現行の規格では ForwardIterator が候補になるだろう。 しかしここも std::for_each() に倣って InputIterator とするのが正解だろう。
401 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:13:19 ] なんなんだよ、typeof()って? 初めて聞いたぞ。 type_infoクラスとtypeid演算子ならC++にあるけど、 typeof()は何をするためのもの?
402 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:21:18 ] >>401 まず最初に言っておくと、typeofは今のところまだ標準には無い。 で、まぁ名前の如く変数の型を得る演算子(?)の事。 Type a; typeof(a) b = a; みたいに使える。 この例では a の型が分かってるけど、Expression Template なんかの場合はどえらい事になっちゃうっしょ。 って分かりにくいかなぁ。誰か分かりやすい例キボンヌ。
403 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:27:44 ] その程度だとtypeid, type_infoとどう使い方が違うのか見えんな。
404 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:29:18 ] テンプレート宣言の template<typename HOGE> を適宜、 template<typename HOGE, typename PLUS_TYPE> にすれば回避できるんじゃないの? 曖昧さの解決にもなるし。 というか、C++とtypeof()は相性が最悪な気がする。 多重継承さえ嫌がる人が多いというのに、 typeof()は、無駄にデバッグ作業を増やさせるだけではないか?
405 名前:デフォルトの名無しさん mailto:sage [05/03/14 01:31:35 ] >>400 ForwardIteratorが正しいね。 しかし、InputIterator で要素の変更を行うのは論外では? for_each()は変更を伴わない関数。 本質的に違う関数に倣うという理由付けも理解に苦しむ。
406 名前:デフォルトの名無しさん mailto:sage [05/03/14 02:01:52 ] >>405 std::for_each() で要素の変更は許される方向にあるらしい。 ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#475 「いまさら禁止されては困る」という本音が多分にあるだろうと思うので、 明示的に許可を後付けされてもすっきりしないよな。 はっきりと Mutating algorithm に移動させて欲しい。
407 名前:デフォルトの名無しさん mailto:sage [05/03/14 08:46:06 ] >>403 オマエの目は節穴なのでしょうか?
408 名前:402 mailto:sage [05/03/14 11:23:16 ] >>403 うーん、例が悪いでしょうかねぇ。ただ、typeidと決定的に違うのが、 「コンパイルタイムに決まる」、という事。 んだから、「謎の型を宣言、定義可能」って事なんですけどね。 明日から海外飛ぶんで誰かフォローよろ。
409 名前:デフォルトの名無しさん mailto:sage [05/03/14 12:32:23 ] 俺も来週から地方飛ばされるんで 誰か助けてくれ
410 名前:デフォルトの名無しさん mailto:sage [05/03/14 12:37:00 ] 俺はneetなんである意味助けてくれ
411 名前:デフォルトの名無しさん mailto:sage [05/03/14 12:37:50 ] >>408 ,409 そのままキャッチされない例外に飛ばされて人生の強制終了。
412 名前:デフォルトの名無しさん mailto:sage [05/03/14 12:43:12 ] C++よりMLの方がいいよ。
413 名前:デフォルトの名無しさん mailto:sage [05/03/14 12:45:00 ] メーリングリスト
414 名前:396 mailto:sage [05/03/14 23:32:14 ] >>397 ,398,400,401,405,406 参考にしたいと思います。ありがとうございます。
415 名前:デフォルトの名無しさん mailto:sage [05/03/15 00:04:29 ] C++よりMLの方がいいよ。
416 名前:デフォルトの名無しさん mailto:sage [05/03/15 00:16:03 ] >>412 >>415 利点をあげてくれ、なにがいいのかわからん
417 名前:デフォルトの名無しさん mailto:sage [05/03/15 00:47:28 ] このスレが不要になるぐらい明快
418 名前:デフォルトの名無しさん mailto:sage [05/03/16 07:47:07 ] そうか、typeofはgccとintel以外じゃ使えないのか。 クラス階層のメンバを辿るときとか便利なんだよな。 node->get_parent()->get_view() とかで参照をとるとき、一回だけだと その場に書くけど長いと面倒なので何か別名を割り当てるためだけに ローカル変数に代入するわけだ。 そういうとき、 #define LET(var,exp) typeof(exp) var = (exp) とかすると VeryVeryLongClassName parent_view = node->get_parent()->get_view(); のかわりに LET(panent_view, node->get_parent()->get_view()); と書ける。非常にラクチン。 boostのlambdaみたいにすればtypeofなしでも同じようなことができるかも。
419 名前:デフォルトの名無しさん mailto:sage [05/03/16 08:08:57 ] >>418 boost spirit typeof
420 名前:418 mailto:sage [05/03/16 09:26:00 ] どうもboostの定義をみてるとMetrowerksにもtypeofがあるようだ。 んで、typeofのテンプレートによる実装もあるみたいだね。 aspn.activestate.com/ASPN/Mail/Message/boost/2504137 boostのsandboxにtypeofの実装があるらしい aspn.activestate.com/ASPN/Mail/Message/boost/2504137 Code Projectの記事。typeofのVC7用実装。 これによるとboost::mplにも BOOST_MPL_AUX_REGISTER_TYPE(123, abc); abc aa1; BOOST_MPL_AUX_TYPEOF(_, aa1) *aa2 = &aa1; というtypeofがあるらしいがundocumentedだのuglyだの不便だのと切って捨てている。 >>419 ? よくわからんちん。
421 名前:デフォルトの名無しさん mailto:sage [05/03/16 15:39:09 ] >>420 boost.cppll.jp/HEAD/libs/spirit/doc/subrules.html typeofはレビュー待ちの状態だと以前読んだ希ガス
422 名前:デフォルトの名無しさん mailto:sage [05/03/16 16:23:33 ] >>420 Metrowerks CodeWarriorでの話。 __typeof__()演算子があって、これは常に使える。typeof()演算子を使うには #pragma gcc_extensions onとする必要がある。こうすると、以下のGNU Cの言語 拡張機能を利用します。 ・auto変数の構造体、または配列を、定数以外の値で初期化することを許可します。 ・sizeof( void ) == 1 ・sizeof( function-type ) == 1 ・評価式の内部のGCCステートメントと宣言を、制限付きでサポートします。 ・#undefがその前にないマクロの再定義。 ・GCCのtypeofキーワード。
423 名前:デフォルトの名無しさん mailto:sage [05/03/17 09:40:37 ] >418 >boostのlambdaみたいにすればtypeofなしでも同じようなことができるかも。 逆だと思いますよ.lambdaも状況は似たようなもので むしろlambdaもtypeofがあればいろいろうれしいです. でもboostのtypeofの実装はさすがにやりすぎな気が・・・ そもそもtypeofの機能をライブラリで提供する/できるというのが異常というか
424 名前:418 mailto:sage [05/03/17 10:10:08 ] 420のCode Projectの方のリンクが寝惚けてました^^; 正しいのはこっち。 www.codeproject.com/vcpp/stl/typeof.asp >>421 すいません、あいかわらずよくわかりません。subruleが普通のコードでも使え るってこと? 数字を手で入れる必要があるのは面倒なような……。 >>422 補足サンクスです。そうそう、__typeof__でした。 そうか、MetrowerksはGCC拡張を一部サポートするんですね。
425 名前:デフォルトの名無しさん mailto:sage [2005/03/25(金) 00:52:31 ] gcc 3.4のバグだろうか。 テンプレート関数の中で boost::mpl::identity<typeof(foo->get_bar())>::type bar; と変数を定義しようとすると何故か expected `;' before "bar" というエラーになる。 普通の関数の中なら問題なく通るのだけど。
426 名前:デフォルトの名無しさん mailto:sage [2005/03/25(金) 00:58:26 ] >>425 typname
427 名前:デフォルトの名無しさん mailto:sage [2005/03/25(金) 02:26:51 ] >>426 サンクス。 typenameは試したはずなんだけど……と思いつつやってみると コンパイル通りました。吊ってきます。
428 名前:デフォルトの名無しさん mailto:sage [2005/03/30(水) 01:09:51 ] Boost.Serialization の #include <boost/serialization/shared_ptr.hpp> にある #define private public #include <boost/shared_ptr.hpp> #undef private って、shared_ptr の方を変更してもらえないんですかね? 別のスレッドで Boost.Serialization を教えてもらったんですけど、 これが、ちょっと気になります……。
429 名前:デフォルトの名無しさん mailto:sage [2005/03/30(水) 01:17:26 ] 変更して貰えるわけないだろ、氏ね(ここまで一筆書き)
430 名前:428 mailto:sage [2005/03/30(水) 02:21:20 ] >>429 Boost 同士ということで friend にしてもらうくらいなら、 と思ったんですが、直接には関係しない物のために変更するのは、 やっぱり無理ですよね。
431 名前:デフォルトの名無しさん mailto:sage [2005/03/30(水) 04:00:47 ] そういうのはここで訊くよりboostのメーリングリストを検索した方がいいのでは。
432 名前:428 mailto:sage [2005/03/30(水) 05:05:42 ] >>431 読んでも分からなさそうと言う事で避けてました。すみません。 で、検索してみたら、そのままの議論がありました。 が、やっぱり分かりませんでした。orz ただ使うだけにします。ありがとうございました。
433 名前:デフォルトの名無しさん mailto:sage [2005/03/30(水) 05:40:36 ] そういう場合はスレッドのURLとか貼っておくといいかもね。
434 名前:デフォルトの名無しさん mailto:sage [2005/03/30(水) 13:22:32 ] Serializetionがオブジェクトを覗き見しなきゃいけないことを>>428 は理解してないのか? shared_ptrの方で変えたら、通常利用で保護出来ないじゃないか。
435 名前:デフォルトの名無しさん mailto:sage [2005/03/30(水) 13:57:46 ] >>434 >>430
436 名前:ヽ(´ー`)ノ ◆.ogCuANUcE mailto:sage [2005/03/30(水) 18:14:32 ] これかな? lists.boost.org/MailArchives/boost/msg74873.php
437 名前:428 mailto:sage [2005/03/31(木) 11:07:00 ] >>436 それです。 shared_ptr の人も交えて、実装に立ち入った問題点などが議論されていて、 日頃使っているだけの私では、良く分かりませんでした。
438 名前:ヽ(´ー`)ノ ◆.ogCuANUcE mailto:sage [int 2ch =05/04/01(金) 20:35:21 ] >>437 つか、Thread Index で変なとこに飛ばされて、 議論が追っかけずらいんだよね(´・ω・`)
439 名前:デフォルトの名無しさん mailto:sage [int 2ch =05/04/01(金) 23:10:42 ] >>438 thread.gmane.org/gmane.comp.lib.boost.devel/113499
440 名前:デフォルトの名無しさん [2005/04/10(日) 19:16:42 ] Spiritのアクションってなんで2引数必要なの? 値を代入したい時は冗長になるぅ... expr = (str_p(L"1"))[boost::lambda::_1,boost::lambda::_2,data=1];
441 名前:デフォルトの名無しさん mailto:sage [2005/04/12(火) 10:09:35 ] template<class T> class A { public: A(const A&); // 引数 A func() // 返り値 { A a; // 自動変数 return a; } }; クラステンプレートで上記のコメントのところのように Aとだけ書いた場合A<T>と同じ意味になる、という解釈は正しいですか?
442 名前:デフォルトの名無しさん mailto:sage [2005/04/12(火) 10:39:06 ] >>441 正しいです。 ttp://www.kuzbass.ru/docs/isocpp/template.html#temp.local
443 名前:441 mailto:sage [2005/04/12(火) 11:09:04 ] >>442 ありがとう。よくわかりました。
444 名前:デフォルトの名無しさん mailto:sage [2005/04/22(金) 04:23:40 ] 鬼車みたいに マルチバイトで正規表現使えると速度面では有利なのかな? ワイド文字で System.Text.RegularExpressions(C#) boost::wregex boost::expressive boost::spirit 試してみたけど敵わなかった... 鬼車>>C#>=boost::wregex>>expressive>>>>>>spirit
445 名前:444 mailto:sage [2005/04/22(金) 04:52:13 ] >>444 spiritのパーサの型がわからんかったんで 毎回生成してたは...道理で遅いはずや... typeid(parser).name()で出力された型にparser保存してループ回したら 鬼車=spiritになったわ... 逝ってくる...
446 名前:デフォルトの名無しさん mailto:sage [2005/04/22(金) 21:22:11 ] CommonLispの正規表現が最速
447 名前:デフォルトの名無しさん mailto:sage [2005/04/22(金) 23:32:46 ] >>445 当たり前だ。C++が遅かったら、コンパイラ言語を使って正規表現を扱う意味が ないやんけ。
448 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 01:11:14 ] コンパイラ言語? 式テンプレートを使ったメタプログラミングのこと?
449 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 09:45:54 ] インタプリタ言語と比較してるだけっしょ
450 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:03:21 ] またなんかミクロな揚げ足取りしてるんだろうね、きっとw
451 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:19:30 ] >>448 友達いないでしょ。
452 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:23:08 ] >>448 どういう風に表現すれば一番適切なのか教えて。 >>450-451 おまえらはどうでも良い。
453 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:31:09 ] 言い負けるのが余程悔しいんだろうな。 リアルな世界では気の強さが災いして、友達どころか彼女もいないと思われる。 家族にも総スカン。
454 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:32:56 ] >>453 どうしてそういう返事をつけるのかな? 普段よっぽど抑圧されてるのか? もっと自分を愛そうね。
455 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:36:57 ] スレタイ嫁
456 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 10:51:39 ] >>447 は、C++のコードをコンパイルして実行から速いと言っているのか、 汎用のDFSマシンじゃなくて、式テンプレートを使ったメタプログラミングで、 専用レクサーを生成して実行しているから速いと言っているのか、 どっちなんだ? 両方か?
457 名前:デフォルトの名無しさん mailto:sage [2005/04/23(土) 17:26:58 ] >>456 真性のアフォ?
458 名前:デフォルトの名無しさん mailto:sage [2005/04/24(日) 04:51:27 ] GCC 4.0.0 に TR1 が来ましたね。うれしい。 ソースは boost のごちゃごちゃしたコンパイラ分岐が無くなった分、 だいぶすっきりした印象
459 名前:445 mailto:sage [2005/04/24(日) 10:46:47 ] spiritの型導出のためにファイル登録型のtypeof作ってみた。 #pragma once #include<fstream> #include<string> #include<typeinfo> template <typename T> struct id_of{enum {val=1};}; template <int N> struct id_to_type{}; template <> struct id_to_type<1>{}; #include"type_id_dynamic_impl.h"//(初回は空ファイルを用意) template<typename T> struct sized { char size[id_of<T>::val]; }; template<typename T> sized<T> obj_class_id_helper(const T&); #define obj_class_id(x) sizeof(obj_class_id_helper(x).size) #define typeof(x) id_to_type<obj_class_id(x)>::type
460 名前:445 mailto:sage [2005/04/24(日) 10:47:24 ] template<typename T> static void make_typeof(const T&,int ID) { std::string class_name = (std::string)(typeid(T).name()); for(int i=0;i<class_name.length();i++){ if(class_name[i]==':')class_name[i]=';'; else if(class_name[i]=='<')class_name[i]='('; else if(class_name[i]=='>')class_name[i]=')'; } std::string include_filename = "type_id_dynamic_impl_"+class_name+".h"; std::string include_file = "#include\""+include_filename+"\""; std::fstream fo_d( "type_id_dynamic_impl.h" ); std::string buf;bool check=false;std::istream si(fo_d.rdbuf()); while(std::getline(si,buf)) if( buf==include_file ) check = true; if(!check) fo_d << include_file << std::endl; fo_d.close(); std::ofstream fo( include_filename.c_str() ); fo <<"#pragma once" << std::endl; fo << "template <> struct id_of< " << typeid(T).name() << " > { enum{ val = " << ID << " }; };" << std::endl; fo << "template <> struct id_to_type< " << ID << " >{ typedef " << typeid(T).name() << " type; };" << std::endl; fo.close(); }
461 名前:445 [2005/04/24(日) 10:49:54 ] int main() { int a=100; make_typeof(a,1212);//初回に必要 typeof(a) aa=100;//make_typeof実行後に有効 }
462 名前:デフォルトの名無しさん mailto:sage [2005/04/25(月) 22:32:41 ] これってtypeofを使う前にmake_typeofを書いた実行ファイルを走らせないといけないですよね? 実用上かなり使いにくくないですか?
463 名前:445 [2005/04/26(火) 00:50:17 ] >>462 それは承知の上、自動で登録できる代償だと思ってる。 でも、type_id_dynamic_impl.hを書き換えるだけにすべきだろうな... (ファイル大量発生とMAX_PATH超えちゃう問題あるだろうし) 登録してない場合はこんな感じでコード切り替えりゃ済む問題だし、 常用できないという点には同意。 #if if_exist_typeof(a) typeof(a) aa=100; #else make_typeof(a,1212); #endif
464 名前:デフォルトの名無しさん mailto:sage [2005/04/26(火) 00:53:50 ] BOOST_TYPEOF_REGISTER_TEMPLATEは飾りなんです 偉い人にはそれがわからんのです
465 名前:Lispのマクロテンプレート mailto:sage [2005/04/26(火) 01:04:31 ] 俺の話を聴け〜♪ 五分だけでいい〜♪
466 名前:デフォルトの名無しさん mailto:sage [2005/05/07(土) 00:44:34 ] 俺しかいない羊羹マン
467 名前:デフォルトの名無しさん mailto:sage [2005/05/07(土) 00:47:41 ] ノシ
468 名前:デフォルトの名無しさん mailto:sage [2005/05/08(日) 12:54:43 ] 質問です。 以下の要件を満たす型に対するtemplate class の 特別バージョンを作ろうと考えています。 ・任意のContainer ・Container::value_typeがstd::pair ・Container::value_type::first_typeがint ・Container::value_type::second_typeは任意 例えば以下のようなものです。 std::vector<std::pair<int, int> > std::deque<std::pair<int, char*> > std::map<int, std::string> これを実現するのに、どういった記述を行えばよいのでしょうか? template<typename T> // これが一般の型を対象としたtemplate class である場合 class A { //... }; template<typename T, typename U> // ここらの書式は? class A { // ここは? // ?????.... }; よろしくお願いします。
469 名前:デフォルトの名無しさん mailto:sage [2005/05/08(日) 13:28:55 ] >>468 ↓で map_with_string 以外は成功するみたい。(@ g++ 3.4.1) そう簡単じゃないな。 #include <utility> template< typename T > struct A { static bool const is_specialized = false; }; template< template< typename > class ContainerTemplate , typename PairSecond > struct A< ContainerTemplate< std::pair< int , PairSecond > > > { static bool const is_specialized = true; }; #include <vector> #include <deque> #include <map> #include <string> #include "boost/static_assert.hpp" typedef std::vector<std::pair<int, int> > vector_with_int; typedef std::deque<std::pair<int, char*> > deque_with_pchar; typedef std::map<int, std::string> map_with_string; BOOST_STATIC_ASSERT( A< vector_with_int >::is_specialized ); BOOST_STATIC_ASSERT( A< deque_with_pchar >::is_specialized ); BOOST_STATIC_ASSERT( A< map_with_string >::is_specialized );
470 名前:468 mailto:sage [2005/05/08(日) 14:04:40 ] ありがとうございます。なんか凄い構文ですね… vector,dequeとmapの特別バージョンを一緒に出来ない件に関しては、 以下のような感じでごまかすことにします。 template <typename T> struct Base { // implementation static bool const is_specialized = true; }; template < template <typename> class ContainerTemplate, typename PairSecond> struct A<ContainerTemplate<std::pair<int, PairSecond> > > : public Base<A<ContainerTemplate<std::pair<int, PairSecond> > > > { }; template < template <typename, typename> class ContainerTemplate, typename PairSecond> struct A<ContainerTemplate<int, PairSecond> > : public Base <A<ContainerTemplate<int, PairSecond> > > { };
471 名前:468 mailto:sage [2005/05/08(日) 14:56:37 ] すみません、訂正です。 : public Base<ContainerTemplate<std::pair<int, PairSecond> > > : public Base<ContainerTemplate<int, PairSecond> > でした。
472 名前:デフォルトの名無しさん mailto:sage [2005/05/08(日) 22:00:30 ] std::vector<int, MyAlloc>なんかが、特殊化される悪寒w
473 名前:デフォルトの名無しさん mailto:sage [2005/05/09(月) 11:32:52 ] std名前空間のものを std名前空間のもので特殊化ないし部分特殊化するのは 可能だがやっちゃダメ
474 名前:デフォルトの名無しさん mailto:sage [2005/05/09(月) 12:36:59 ] >>472 MyAlloc どころか普通の std::vector<int> も特殊化される罠 >>473 この場合、特殊化してるのは vector/deque/map じゃなくて A のほうだから問題ないんじゃないかと思うんだが
475 名前:468 mailto:sage [2005/05/09(月) 13:06:57 ] Baseで typedef typename T::value_type::first_type first_type とか、諸々のstatic_assert置いておけばなんとかなると踏んでたんですが、 やっぱ変でしたかねぇ。
476 名前:468 mailto:sage [2005/05/09(月) 13:22:32 ] たびたびすみません、これだとA<std::vector<int> >が作れないや。 勉強して出直します。
477 名前:473 mailto:sage [2005/05/09(月) 16:30:48 ] >>474 あ、>>468 のvector,deque等の例に対して言ったんです。
478 名前:468 mailto:sage [2005/05/09(月) 17:44:25 ] >>473 468では、Aに渡す型の例としてvector,dequeをあげたのであって、 vector,dequeの特別バージョンを作ることを意図したわけではないのです。
479 名前:デフォルトの名無しさん mailto:sage [2005/05/09(月) 18:19:20 ] >468 ユーザ定義型が絡む場合ならば,std::vector等のstd名前空間内のテンプレートを 特殊化することは許されているんですけれどね. そもそも468は恐らくソート済みシーケンスとstd::mapを汎用に扱おうとする意図だと 思いますけれど,これらは各種メンバ関数の宣言その他もろもろからして違うので 汎用に扱おうとするのはかなり無理がないですか?
480 名前:468 mailto:sage [2005/05/09(月) 18:44:11 ] 何度もすみません。 >そもそも468は恐らくソート済みシーケンスとstd::mapを汎用に扱おうとする意図だと >思いますけれど, その通りです。 >これらは各種メンバ関数の宣言その他もろもろからして違うので >汎用に扱おうとするのはかなり無理がないですか? 無理がありました(汗 いろんなことが出来ませんでした。 とりあえず設計が悪かったということみたいです。
481 名前:デフォルトの名無しさん mailto:sage [2005/05/09(月) 18:52:39 ] >480 それがやりたいならstd::vectorやstd::dequeをラップして std::mapの要求に合うようにするアダプタ作るのが恐らく最良じゃないかと思います. それを状況に応じてstd::mapととっかえひっかえする感じで.
482 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 00:38:29 ] boostにそんな感じのクラスなかったっけ? 似たようなニーズがあってboostを眺めたらあったので後で余裕があったら使おうと 思いつつ、遅いけどその場はstd::listで済ませたという覚えがある。 そういやその後試してなくてそのままになってるな。
483 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 00:43:11 ] multi_index_container
484 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 00:59:28 ] >>482 キーと値のアクセスの汎用化、ということなら property_map なんかもそうかな。 あとは boost-sandbox に associative_vector,vector_set なんてのもあるみたいだね。
485 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 01:05:27 ] >>480 まあ実用性のことは置いておいて、メタプログラミングのいい勉強になるかな、 と思ってちょっと書いてみた。 ここは BOOST スレじゃないので、敢えて boost::mpl とかは使わず。 template <class T0, class T1> struct is_same_type { static const bool value = false; }; template <class T> struct is_same_type<T, T> { static const bool value = true; }; struct sfinae_type { typedef char one; typedef struct { char arr[2]; } two; }; template <class T> struct has_key_type : sfinae_type { template <class U> static one test(typename U::key_type*); template <class U> static two test(...); static const bool value = (sizeof(test<T>(0)) == 1); }; template <class T> struct has_value_first_type : sfinae_type { template <class U> static one test(typename U::value_type::first_type*); template <class U> static two test(...); static const bool value = (sizeof(test<T>(0)) == 1); };
486 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 01:06:01 ] template <class T, bool HasKeyType, bool HasValueFirstType> struct A_specialized_impl { static const bool value = false; }; template <class T, bool HasValueFirstType> struct A_specialized_impl<T, true, HasValueFirstType> { static const bool value = is_same_type<int, typename T::key_type>::value; }; template <class T> struct A_specialized_impl<T, false, true> { static const bool value = is_same_type<int, typename T::value_type::first_type>::value; }; template <class T> struct A_specialized : A_specialized_impl< T, has_key_type<T>::value, has_value_first_type<T>::value > {}; template <class T, bool Specialized = A_specialized<T>::value> struct A { ... }; // 通常版 template <class T> struct A<T, true> { ... }; // 特殊化版
487 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 02:23:21 ] >485 細かいことですけどmapのkey_typeってconstですよ. SFINAEのこういう使い方はあくまで 「必要条件を満たさないものを振り落とす」ってだけなんですよね. それにできることが基本的な型特性と内部型の存在のテストくらいだし・・・. せめてメンバ関数の存在をテストできればもう少し面白いと思うんですけれど.
488 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 03:24:21 ] >>487 いや、value_type が pair<const Key, T> なのであって、 key_type は Key のままだよ。 そうでないと一時変数作れないし。
489 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 09:27:04 ] >>487 > せめてメンバ関数の存在をテストできればもう少し面白いと思うんですけれど. typeof(メンバ関数)で何とかなります。
490 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 10:28:50 ] >488 マジボケしてました・・・. >489 何とかなります?typeofってそもそも非標準ですし.
491 名前:ヽ(´ー`)ノ ◆.ogCuANUcE mailto:sage [2005/05/10(火) 10:36:09 ] >>490 まだ sandbox だけど boost::typeof とか。 boost スレかどっかで見たけど、どこだったか忘れた。
492 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 14:30:49 ] >>489 これとか見ると、メンバ関数のシグネチャが分かれば なんとかできそうな気はする ttp://lists.boost.org/MailArchives/boost/msg70844.php
493 名前:デフォルトの名無しさん mailto:sage [2005/05/10(火) 22:34:40 ] >>491 typeofがあってもメンバがなければ単にコンパイルが失敗するだけじゃないですか? >>492 汎用プログラミングの文脈だと「〜〜というシグネチャを持ったメンバ関数があるかどうか」というテストより 「〜〜という構文でメンバ関数が呼び出せるかどうか」というテストの方が重要だと思うので, そこで使われている技法は少なくとも汎用プログラミングでは非常に使いづらいような気がします. それにその技法,言語規格的に結構スレスレなことやってるので,GCCではうまく通らなかったり VC7.1でもうまく機能しないケースがあったり・・・.
494 名前:デフォルトの名無しさん mailto:sage [2005/05/11(水) 00:30:14 ] >>493 > typeofがあってもメンバがなければ単にコンパイルが失敗するだけじゃないですか? traitsみたいなんじゃ不十分で、条件分岐とかしたいという事?
495 名前:ヽ(´ー`)ノ ◆.ogCuANUcE mailto:sage [2005/05/11(水) 10:34:33 ] >>493 失敗するだけだね。boost::mpl::has_xxx とかで何とかできないかとも思ったが、 寝不足なせいか、頭がこんがらがってきた。
496 名前:デフォルトの名無しさん mailto:sage [2005/05/11(水) 19:59:54 ] >>494 そうです.traitsというよりはintrospectionといったほうが適切ですかね. traitsはユーザが明示的に特殊化する分,確実ですけれど一方で面倒な側面もあると思うので, ある程度は要件を自動的にテストしてくれたほうが楽かなという発想です. >>495 boost::mpl::has_xxxは内部型の存在テストにしか使えないです.
497 名前:デフォルトの名無しさん mailto:sage [2005/05/12(木) 00:23:09 ] >>496 > そうです.traitsというよりはintrospectionといったほうが適切ですかね. traitsとも違い、 virtual classをinheritしたり、 interfaceをimplementsするのとは違う用途は、 具体的にどういうものを想定しているんですか?
498 名前:デフォルトの名無しさん mailto:sage [2005/05/12(木) 03:28:39 ] >>497 >具体的にどういうものを想定しているんですか? いや,あまりろくなことを考えていないんですが,一応,型がどのコンセプトの モデルなのかを識別するための手段として使えないか,と想定していました. 型がどのコンセプトのモデルであるかを識別できれば,クラステンプレートの特殊化や 汎用関数のオーバーロード選択をより柔軟にできるんじゃないかという考えです.例えば template<class Iterator, class T> void replace(Iterator first, Iterator last, T const &x); という汎用関数があって,TがIteratorの値型に変換可能な型ならstd::replaceの機能で, TがIteratorの値型を受ける単項述語ならstd::replace_ifの機能といった具合です. 逆に言うと,STLはこのようなコンセプトに基づいたオーバーロード選択の技術がないので replaceとreplace_ifとに名前を分けざるを得なかった,とも言えると思います. で,仮に例えばTのoperator()がIteratorの値型で呼び出せるかどうかを テストできるような実装技術があれば,traitsの明示的な特殊化に頼ることなく 上記のような高度な振り分けができるんじゃないか,という考えです. ただ,もちろんメンバ関数の存在テストはコンセプトの必要条件を調べられるだけで, 決してコンセプトのモデルであるための十分条件を調べることにはならないのですが・・・.
499 名前:デフォルトの名無しさん mailto:sage [2005/05/12(木) 03:29:37 ] ・・・ということを想定していたんですが, tinyurl.com/as9k5 上のような議論を見つけたので読んでみた結果,やはりtraitsの特殊化などで 明示的に表明する方が良いような気がしてきました.より根本的には 言語としてこういうことを直接サポートしてくれればもっとうれしいのですけれど. www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1758.pdf
500 名前:デフォルトの名無しさん mailto:sage [2005/05/12(木) 12:05:02 ] 上記PDFもそうだけど、D&Eの書き下ろし前文(-1章)を見ても、 コンセプト回りの拡張が c++0x でなされる可能性は高いんじゃないかな。 ただ、Stroustrup としても テンプレート回りのエラーメッセージの酷さを何とかすることや、 テンプレート宣言と定義の分離問題を何とかするために導入したいような 感じだし、基本的にはコンパイル時検査の強化を目的としたものであって、 オーバーロード選択などに使われるようなものではないと思う。 例えば、関数ポインタのシーケンスがあったとして、 operator== による find なのか、operator() による find_if なのか、 コンセプトだけでは判断できないケースもあるわけで。
501 名前:デフォルトの名無しさん mailto:sage [2005/05/12(木) 19:39:36 ] >>500 > 使われるようなものではないと思う。 けど,使われるようなものではないものに,使われて驚くのがtemplateだしなあ…
502 名前:デフォルトの名無しさん mailto:sage [2005/05/13(金) 01:07:52 ] >>500 >テンプレート回りのエラーメッセージの酷さを何とかすることや、 >テンプレート宣言と定義の分離問題を何とかするために導入したいような これは前々からずっと言ってますからねぇ.近い将来標準に導入されると信じていますけれど. >例えば、関数ポインタのシーケンスがあったとして、 >operator== による find なのか、operator() による find_if なのか、 >コンセプトだけでは判断できないケースもあるわけで。 う,やはりここ突っ込まれますよね・・・.こういう曖昧なケースではユーザが 明示的に曖昧性を解消するような方向を想定してました.微妙ですけれど. やはり現在の段階では,コンセプトに基づくオーバーロード選択や テンプレートの特殊化といった発想は飛躍しすぎている感がありますね.
503 名前:デフォルトの名無しさん mailto:sage [2005/05/14(土) 03:29:59 ] 参照templateのパラメータに制限あるのかな? グローバル変数しか使えないみたいなんだが... struct A{}; template <A& a>struct C{}; A a;//OK int main() { A a;//NG C<a> c; }
504 名前:デフォルトの名無しさん mailto:sage [2005/05/14(土) 05:10:48 ] >503 14.3.2 Template non-type arguments 4 [Note: Temporaries, unnamed lvalues, and named lvalues that do not have external linkage are not acceptable template-arguments when the corresponding template-parameter has reference type. 14.3.2-1 の補足。
505 名前:デフォルトの名無しさん mailto:sage [2005/05/14(土) 09:10:05 ] テンプレートはコンパイル時に生成されるわけで mainの方のaは実行してみないとどこに作られるかわからないわけで そのaをテンプレート引数にstruct Cは生成できないわな。
506 名前:デフォルトの名無しさん [2005/05/15(日) 21:00:03 ] VisualC++7.1なんですが、テンプレートコンストラクタの明示的なインスタンス化をしたいんですが コンパイルが通りません。なぜでしょうか? class A { public: template< typename B > A( B b){;} }; template< > A::A< int >( int b); // error C2143: 構文エラー : ';' が '<' の前にありません。 他 template A::A< int >( int b); // error C2143: 構文エラー : ';' が '<' の前にありません。
507 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 21:28:04 ] >>506 ttp://www.kuzbass.ru/docs/isocpp/template.html#temp.expl.spec ここに明示的な特殊化の対象となるものがリストされているんだが、 "member function template of a class template" はあるけど、 "member function template of a class" は無いな。 できないのかもしれない。
508 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 21:51:51 ] >>506 >>507 多分これ。 14.5.2.5 [Note: because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates. ] コンストラクタは関数名を持たないので、メンバテンプレートにされたコンストラクタおよび 変換メンバ関数テンプレートは明示的に実引数を与えられないって事っすね。 C++の不具合とも言えるので、次期C++規格ではfixして欲しいですな。
509 名前:デフォルトの名無しさん [2005/05/15(日) 21:56:00 ] >>506 理解しました。ありがとうございました。 しかし皆さん凄いですね。
510 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 21:56:33 ] >>506 というわけで 「コンストラクタテンプレートぐらいhppに全部書いちゃえば良いじゃない」 もしくは 「コンストラクタテンプレート内の処理を静的メンバ関数に委譲して (この部分だけはhppに書く必要アリ) 委譲先の静的メンバ関数を明示的にインスタンス化すれば良いじゃない」
511 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 22:32:53 ] ん?これでできてるっぽいぞ。 template<> A::A( int b);
512 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 23:29:21 ] >>511 あれ?本当だね。という事は、template <>の構文がちゃんとメンバテンプレート に適用されているみたいだね。俺の勘では、明示的特殊化になってなくて、単なる オーバーロードのような気もするが・・・・
513 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 23:36:57 ] もう少し規格票をよく読んでみる・・・・・ >>508 はそしたら違う事に関してなのかな。
514 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 23:41:09 ] >>511 しかし、そのコードは構文的に正しいとは言えないですよね。 謎だ。
515 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 23:41:17 ] 特殊化とインスタンス化とを混同してない?
516 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 23:55:33 ] >508が示したように、コンストラクタテンプレートに対して テンプレート引数を明示する方法は無い。 しかし、(メンバ)関数テンプレートの特殊化を宣言する再には、 テンプレート引数を明示しなくても、関数引数の型から テンプレート引数の推測が働く。 >>514 明示的特殊化の構文は template<> delcaration だから、>511は構文的に正しいと言える。
517 名前:デフォルトの名無しさん mailto:sage [2005/05/15(日) 23:58:48 ] 構文的には確かに正しいのだけれど、もともとの506の要求は 明示的インスタンス化(≠明示的特殊化)なわけで・・・
518 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 00:02:05 ] 勉強になった。
519 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 00:08:01 ] >>517 それがどうした? 明示的インスタンス化の構文は template declaration だ。あとは同じ。
520 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 00:12:53 ] >>519 すまんすまん。それでVC++7.1で通ったよ。
521 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 00:15:29 ] コンパイラに「これこれのテンプレートをT型でインスタンス化しますた」 とレポートするスイッチがあればいいのに
522 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 00:17:31 ] 実体化の位置を決定するルールは結構複雑だからな。
523 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 00:59:29 ] おまえらの必死さに笑った。 C++の中途半端なtemplate機能でメンテ不能の駄作を量産してる様は、 まるでVBで汎用ライブラリを作る馬鹿とそっくりだな。
524 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 01:03:16 ] C++知らないのに、知ってる振りして がんばって煽るアンタもそうとう必死だが
525 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 01:35:46 ] むしろC++で駄目なのは テンプレートじゃなくてコンストラクタ
526 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 01:47:19 ] >>525 コンストラクタの何が不満だって?
527 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 02:48:50 ] 純粋なOO言語と比べると C++のOOは不完全
528 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 03:05:21 ] >>526 class A { int a; public: A( int a_ ) : a(a_){;} }; class B : A { public: B(){ int a = 略; A::A(a);} B( int a ) : B(){;} };
529 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 03:16:11 ] 何がしたいのか理解に苦しむ。C++について理解しているとは思えないコードだ。
530 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 03:30:52 ] >>529 これが出来ないから嫌だなと。 >B(){ int a = 略; A::A(a);} これはAに突っ込む引数aを Bのコンストラクタ内で生成したい時。 C++ではAのコンストラクタは、Bの初期化リストにしか 置けないので複雑なロジックは難しい。 >B( int a ) : B(){;} これは多重定義したコンストラクタから デフォのコンストラクタを予呼びたい時。 デフォのコンストラクタに生成時にかならず呼ばれる 初期化コードを収める。 これが出来ないと全てのコンストラクタに 同じ初期化コードを書かなければならない。
531 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 04:43:03 ] >>530 最初の:AはBの基底クラス。最初にAが構築されなきゃBが構築できない。 2番目の:B() {Init();} B(int a) {Init();hogehoge(a);}
532 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 08:55:21 ] 最初のは static int hoge() {return 略} B() : A(hoge()) {} とかすれば。
533 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 09:05:50 ] >>530 そういうことか。 ではどうしたらいいと思う? Dは両方いけるんだっけか?
534 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 09:06:24 ] >>531 > Aが構築されなきゃBが構築できない 関係ない。 > Init() Init() の中に初期化リストが書けない。
535 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 09:07:23 ] >>532 hoge() の値を初期化リストで2度使いたくなったらやっぱり困るな。 「略」が軽くて副作用がなければ、2回呼び出すんだろうけど。
536 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 09:10:37 ] 要は設計が悪いんだろ。
537 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 09:18:31 ] まあそうだな。C++の設計の悪さは今更いかんともしがたい部分がある。
538 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 11:19:33 ] >>530 > C++ではAのコンストラクタは、Bの初期化リストにしか > 置けないので複雑なロジックは難しい。 コンストラクタの途中でexceptionが起きたことを考えると、 >>532 のような方法で初期化リストを旨く使う方法に頭を悩ませるのが良い。 >>528 のやり方ではコンストラクト失敗時のデストラクトの扱いがかなり難しくなる。 初期化リストで上手くできない場合は、 exception safeの事を考えるとコンストラクタ自体がかなり複雑になってしまう。
539 名前:>>538 mailto:sage [2005/05/16(月) 11:21:07 ] 定義順じゃなくて、初期化リスト記述順だといいのになあと思ったことはある。
540 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 12:06:24 ] >>539 それだと、コンストラクタごとに初期化順が変わってしまう。 Ex. class foo { public: foo() : a_(), b_() {} foo(int a) : b_(a), a_(a) {} ...; };
541 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 12:21:40 ] >>540 539はまさにそれを意図しているのだと思うが、何か不都合があるの?
542 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 12:53:52 ] >>541 初期化リストに載ってないメンバはどうすればいい? by コンパイラ
543 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 13:14:10 ] くるしゅうない。よきにはからえ。
544 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 13:17:59 ] 構築した順番の逆順で解体することを保証しなきゃならんので コンストラクタごとに初期化順が変わったら大変だ。
545 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 14:05:33 ] なるほど。それもそうだ。
546 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 15:32:47 ] つーか藻前らEffectiveC++くらい読んどけよ。
547 名前:デフォルトの名無しさん [2005/05/16(月) 20:25:46 ] template< uint n > class X { public: void f(...); } こういうクラスがあったとして、 nが1だった場合 → X::f( uint f0 ); nが2だった場合 → X::f( uint f0, uint f1 ); nが3だった場合 → X::f( uint f0, uint f1, uint f2 ); こういうふうにテンプレート引数によって 関数の引数の数が変わるようにしたいんですが可能ですか? 出来ないまでも、代替手段みたいなのはありますか?
548 名前:デフォルトの名無しさん [2005/05/16(月) 20:53:37 ] あの〜 templateって実はマクロ?
549 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 21:23:34 ] >>547 関数のデフォルト引数でなんとかしろ。同一のテンプレートパラメータの型を 持つクラスは2回以上は定義できん。
550 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 21:58:37 ] >>549 了解、こういうのも出来るといいですね。
551 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 22:15:27 ] いやだから、ディフォルト引き数で何が不満なんだ?
552 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 22:22:47 ] それぞれ特殊化で可能じゃない?もちろんそうするのが良いか悪いかは別。
553 名前:デフォルトの名無しさん [2005/05/16(月) 22:26:17 ] >>551 例えばベクトルクラスがあります。 template< uint n >class vector; これをインスタンス化したい場合、こういうふうに書きたいんです。 vector<2> v2 = vector<2>(5,1); vector<3> v3 = vector<3>(5,1,6); vector<4> v4 = vector<4>(5,1,6,3); vector<5> v5 = vector<5>(5,1,6,3,9); vector<100> v100 = vector<100>(5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9, 5,1,6,3,9,5,1,6,3,9); 自然な欲求だと思います。
554 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 22:31:08 ] >>553 そういう時のためのstd::vectorではないかと思うのだが・・・・
555 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 22:34:16 ] static const uint initialValues[] = {5, 1, 6, 3, 9,}; std::vector<uint> v5 = std::vector<uint>(initailValues, initialValues + sizeof(initialValues) / sizeof(*initialValues));
556 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 22:34:58 ] その例なら 配列を初期化して、std::vectorにぶち込めばいいじゃん どうしてもやりたいならBOOST_PPで特殊化
557 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 23:09:19 ] 部分特殊化。以降略。なんか馬鹿みてえ。 #include <iostream> #include <cstddef> template <std::size_t N, typename T = int> class vec { T a[N]; public: vec(T i) { a[0] = i; std::cout << a[0] << std::endl; } }; template <typename T> class vec<2, T> { T a[2]; public: vec(T i, T j) { a[0] = i; a[1] = j; std::cout << a[0] << ' ' << a[1] << std::endl; } }; int main() { vec<1> v1 = vec<1>(5); vec<2> v2 = vec<2>(5,1); }
558 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 23:21:18 ] 特殊化はイヤというか面倒くさすぎるから、普通はこんなカンジだろうね template<uint Dim> class vector { double *const coord; public: vector(double x) : coord(new double[sizeof(char[Dim == 1]) * Dim]) { coord[0] = x; } vector(double x, double y) : coord(new double[sizeof(char[Dim == 2]) * Dim]) { coord[0] = x; coord[1] = y; } vector(double x, double y, double z) : coord(new double[sizeof(char[Dim == 3]) * Dim]) { coord[0] = x; coord[1] = y; coord[2] = z; } }; int main() { vector<1> v(1); vector<1> v1(1, 2); // error vector<2> v2(1, 2); vector<2> vv2(1); // error vector<3> v3(1, 2, 3); }
559 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 23:24:56 ] やはりコンストラクタのオーバーロードに落ち着くか。
560 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 23:25:18 ] >> そうするまでもなく 普通に多重定義でいいと思うよ。 template <std::size_t N, typename T = int> class vec { T a[N]; public: vec( T x, T y) { if( N > 0 )a[0] = x; if( N > 1 )a[1] = y; } vec( T x, T y, T z) { if( N > 0 )a[0] = x; if( N > 1 )a[1] = y; if( N > 2 )a[2] = z; } };
561 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 23:27:04 ] ちなみに、 sizeof(char[Dim == 1]) ってのは、 Dim == 1 のときは、1 で、そうでなければ、コンパイルエラーね
562 名前:デフォルトの名無しさん mailto:sage [2005/05/16(月) 23:59:25 ] どうも読みにくいので、直した template<unsigned Dim> class vector { double coord[Dim]; public: vector(double x) { sizeof(char[Dim == 1]); // Dim == 1 でなければエラー coord[0] = x; } vector(double x, double y) { sizeof(char[Dim == 2]); // Dim == 3 でなければエラー coord[0] = x; coord[1] = y; } vector(double x, double y, double z) { sizeof(char[Dim == 3]); // Dim == 3 でなければエラー coord[0] = x; coord[1] = y; coord[2] = z; } }; int main() { vector<1> v(1); vector<1> v1(1, 2); // コンパイルエラー vector<2> v2(1, 2); vector<2> vv2(1); // コンパイルエラー vector<3> v3(1, 2, 3); }
563 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 02:55:12 ] おまえらの必死さに笑った。 C++の中途半端なtemplate機能でメンテ不能の駄作を量産してる様は、 まるでVBで汎用ライブラリを作る馬鹿とそっくりだな。
564 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 02:57:49 ] ×メンテ不能 ○俺に理解不能
565 名前:デフォルトの名無しさん [2005/05/17(火) 07:37:28 ] あーあ、4,5,6って別々にするわけ?テンプレの意味ねー
566 名前:デフォルトの名無しさん [2005/05/17(火) 07:41:46 ] テンプレートはマクロ www.iba.k.u-tokyo.ac.jp/〜yanai/template_tips.html
567 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 10:05:48 ] >>563 まあ同意。boostとか見てても思うが、言語使用の範囲内でどうにかしようとするから無理が出てくる。 パズルとしては興味深いが、無理やりやってるからどうしてもキモくなる。 新しいプリプロセッサ作ったほうがマシな気がする。
568 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 12:24:00 ] >>566 典型的なアホっぽいが。 exportはComeauでサポートされていることすら知らんようだし。
569 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 12:40:07 ] >>566 > まず最も重要な事実は、templateはマクロであるということである。 そもそも、始めの仮定についてキチンと論証してない時点でアウトだな。
570 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 13:16:28 ] templateはマクロだよ。 マクロと聞いてCやC++のプリプロセッサ(やVBAなどアプリケーション内のスクリ プティング言語)しか思いつかない人に向けた文章ではなかろ。
571 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 14:01:12 ] >ここではオブジェクト指向に則ったよいtemplateの使い方を模索する。 この時点で道を誤っている気が。
572 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 14:29:53 ] templateの明示的インスタンス化なんて、少し考えれば 使い道などろくに無い機能だとわかるだろうに しかも使う必要も無い機能だし それにこだわってる時点で、ダメだなそのページ
573 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 18:56:42 ] ネタをまじめに叩くなよ
574 名前:デフォルトの名無しさん [2005/05/17(火) 20:39:55 ] ねたじゃねーし templateはコンパイルする前に展開されるからマクロなの
575 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 20:42:50 ] コンパイルする前に展開しちゃったら タイプセーフは無理じゃないの?
576 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 20:47:38 ] いいよわからん奴は無理に使うな
577 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 21:03:14 ] マクロで使える構文を限定的にして型を認識させたのがテンプレート
578 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 21:12:28 ] みんな好き勝手に「マクロ」の意味を定義して使ってるから、話が噛み合わない だけでしょ。
579 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 21:56:51 ] おっと、ここで578が正式にマクロの定義とやらを教えてくれるらしいぞ
580 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 22:03:42 ] なにこの意味不明な反応
581 名前:デフォルトの名無しさん mailto:sage [2005/05/17(火) 22:21:02 ] 付き合うだけ無駄でつ
582 名前:デフォルトの名無しさん [2005/05/18(水) 07:21:54 ] 普通のマクロでも引数の数を変えられるようなことはできないから >>553
583 名前:デフォルトの名無しさん mailto:sage [2005/05/20(金) 00:28:48 ] VC7.1で std::list<int>使うとポインタの保存のためか std::vector<int>の3倍近いメモリ使うんだが、 省メモリな実装のlistって無理なのかな?
584 名前:デフォルトの名無しさん mailto:sage [2005/05/20(金) 00:55:57 ] >>583 SGI STLのstd::slistなら、一方向リストだけど、少しでも少ないかも。
585 名前:デフォルトの名無しさん mailto:sage [2005/05/20(金) 01:45:41 ] リストすら作りを理解してないのかよ。
586 名前:デフォルトの名無しさん mailto:sage [2005/05/20(金) 12:25:58 ] std::vectorのresizeコストが気になるようならstd:;dequeとか
587 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 00:07:18 ] つうか双方向リストは最低2つはポインタが必要なんだから当たり前の気がするんだが
588 名前:583 mailto:sage [2005/05/21(土) 00:47:56 ] サイズは可変で大きい、挿入削除が定数時間(->list)、省メモリ(->vector) を同時に満たしたかったので... とりあえず挿入削除の速いlistを選択したけど、以外とメモリ食うって分かった。 小規模のvectorをlistで繋ぐか584さんのslistつかうのがいい気がしてきた。 双方向リストだとポインタが64bit化したらさらに事態は悪化するのも気になるし...
589 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 00:53:20 ] だから小規模なvectorをつなぐぐらいならdeque使えってばよ
590 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 00:54:03 ] >>587 要素が int で、双方向のポインタがあるわけで それぞれサイズが同じなら、int の 3倍ですね。 >>585 も指摘してますが、糞当たり前です。
591 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 00:54:46 ] >588 データ構造の勉強からやり直して来い。
592 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 00:55:27 ] s/int の/1要素あたり int の/
593 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 00:56:22 ] >>588 中身の小さいオブジェクトを入れると、相対的にlistはポインタなどの管理部分が 大きく見えてしまうからねえ。 ケースバイケースで使い分けるしかない。 それとstd::slistのiteratorは、forward iteratorなので、bidirectional iteratorのlist に比べると実行効率の悪いメンバ関数がいくつか存在するから、その点もよく確かめてね。
594 名前:583 mailto:sage [2005/05/21(土) 01:04:49 ] dequeだと 中間への挿入、削除した場合に 参照と反復子が死滅。
595 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 01:05:46 ] >>588 テキストエディタみたいに、挿入が同一箇所に連続して発生するようなら ギャップベクタを検討するといいかも
596 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 01:34:23 ] >>594 それが問題になるなら、もう list しかないんじゃないかなぁ。 「小規模のvectorをlistで繋ぐ」なんてのも、全然ダメだろ。
597 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 01:43:48 ] もはやtemplateの話題じゃなくて、「データ構造とアルゴリズム」の世界だな。
598 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 02:11:25 ] listとかvectorはあるのに、より優れた概念のS式がないのはおかしい
599 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 03:42:02 ] >>598 あなたね(汗 インタプリタじゃないんですから。
600 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 05:55:52 ] >>599 もっと詳しく。 ・・・って言っても無駄か。 何もわかってないくせに噛み付いてるの見え見えだもんな。
601 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 08:25:20 ] S式ってツリー構造じゃ無かったっけ?違った?
602 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 08:41:31 ] >>600 赤黒木だけじゃ足りないってのかい。
603 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 09:18:31 ] >>597 STLネタがそっちに向かうのは自然だと思うけど?
604 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 09:22:59 ] > つうか双方向リストは最低2つはポインタが必要なんだから当たり前の気がするんだが 直前の要素のポインタと直後の要素のポインタの排他的論理和演算結果を保持しておけ。 そうしておけばポインタ1つで双方向からリストをたどることができる。 実行時にそれなりのコストはかかるが、、、
605 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 10:01:07 ] >>604 結局サイズは変わらないわけだが。 しかも「ポインタ同士のXOR」?ワケワカラン。
606 名前:604 mailto:sage [2005/05/21(土) 10:23:45 ] 以下のようなリンクリストがあったとする。 A‐B‐C この時、B のポインタ領域には &A ^ &C となる値がセットされることになる。 順方向でA、Bまで読み込んできた場合、Aのアドレスは判っているはず。 このため、&A ^ (&A ^ &C) を計算することでCのアドレスが取得できる。 同様に逆方向でC、Bまで読み込んでいる場合、Cのアドレスは判っているため、&C ^ (&A ^ &C) を計算することでAのアドレスが取得できる。 これが magic list というデータ構造。
607 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 10:35:12 ] >>606 代償としてイテレータのサイズが大きくなるから、使い道は微妙だけどな。
608 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 10:43:01 ] >>606 ふーん。 std::list の実装に使われてるのは見たこと無いんだけど、 標準コンテナの実装としては何か問題があるのかな? と考えたら、イテレータを取得した後に要素の削除・追加をするとマズイような気がした。
609 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 10:44:00 ] >>604 リストを変更しないときのコストはたいしてかからないんじゃないか。 簡単なループの場合、movl (%eax),%eax が xorl (%eax),%eax になるだけだろう。 >>607 イテレータのサイズなんて問題になることがそうそうあるとは思えんが。 前後に追加削除があるとイテレータが無効になってしまうから std::listとはコンパチにならなくなることの方がまだ問題になりそうだ。
610 名前:604 mailto:sage [2005/05/21(土) 10:50:55 ] >>607 イテレータのサイズとリンクリストに保持される各要素のデータサイズを同列で比較するのもどうかと思うが。 イテレータにポインタを2つほど追加したところで、8バイトしかサイズは増えない。 (処理が複雑化する分、イテレータオブジェクトのサイズはもう少し増えると思うが。) しかし、双方向ポインタにしてしまうと、各要素毎に4バイトの投資が必要となる。
611 名前:604 mailto:sage [2005/05/21(土) 10:58:43 ] >>608 >>609 確かにイテレータの取得後に前後の要素が追加削除されると痛い。 排他制御の問題を抱え込むから、std::list との互換性は考えない方が吉かと。
612 名前:デフォルトの名無しさん mailto:sage [2005/05/21(土) 11:12:46 ] >>609 > 簡単なループの場合、movl (%eax),%eax が xorl (%eax),%eax になるだけだろう。 訂正。これ間違い。xor+mov*2(or xchg)になるな。
613 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 00:18:22 ] > サイズは可変で大きい、挿入削除が定数時間(->list)、省メモリ(->vector) データの格納にset使うのってやっぱダメなのか? setの中身はconst扱いだけど、外してswapして取り出して消して使ってるけど。 挿入時もヌルデータ入れて跡で要素をswapしてるんで無駄なコピーも出ない用に工夫して、、、 、、、、 vectorはサイズ増えると勝手に自分のコピー作るんで、reserveしなきゃならんので嫌だ。 lispは探索が遅いし。mapはそんなものに使うのもったいないし。 結論 : set使え!
614 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 00:31:16 ] setが泣いてるぞ
615 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 00:31:37 ] listのメモリ効率が気になるような状況でsetなんか使えるかよ つーか、dequeって要素へのアクセスもそこそこ速くサイズ変更のコストも最小限なのになんで使われんのか。
616 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 03:41:02 ] >>615 dequeって要素へのアクセスもそこそこ速く ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 環境によってはlist並みに遅いわけですが何か? OSやCPUは敢えて書かないが、STLportとかSTLportとかSTLportとか。
617 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 06:50:59 ] >>606 C++ でポインタにビット毎の論理演算なんて 吉外じみた真似、よく平気で出来ますね。
618 名前:604 mailto:sage [2005/05/22(日) 08:36:41 ] >>617 坊やだな、、、 ポインタと言えど所詮はビット列なのだよ。
619 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 08:39:59 ] >>618 reinterpret_castとか使わないといけないんだろ? 環境依存イクナイ(・A ・)!
620 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 08:55:43 ] >>606 面白いなぁ
621 名前:604 mailto:sage [2005/05/22(日) 08:55:52 ] >>619 reinterpret_castが即、環境依存につながるとは新鮮な考え方だな。 同じ環境内でキャストして、同じ環境内で元に戻すのであれば、環境依存も何もないだろうに(それを環境依存というのなら、コンパイラが吐くコードはすべて環境依存になるぞ)。 それとも、そういうことすら期待できない処理系が現存するというのか? (そんなのが出てきた時点で reinterpret_cast は言語仕様から外されるだろうて。)
622 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 09:07:29 ] >>621 愉快な香具師だなお前。 C++の実装と進化の§14.3.3(P420)読んでみろ。
623 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 09:09:30 ] >>622 ○C++の設計と進化 ×C++の実装と進化 それから、規格票を優先しろ。
624 名前:604 mailto:sage [2005/05/22(日) 09:17:26 ] その本は持ってない。 引用の範囲内だろうから、出典を明記して引用してくれ。 内容を咀嚼して説明してくれてもよいぞ。
625 名前:620 mailto:sage [2005/05/22(日) 09:35:20 ] 俺の面白いは純粋な意味であって、622と同じ意じゃないですよ
626 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 09:38:55 ] 5.2.10 Reinterpret cast 4 A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined [Note: it is intended to be unsurprising to those who know the addressing structure of the underlying machine. ] 5 A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined. 要するに規格としてはポインタ型を整数型にreinterpret_castして その値をそのままポインタ型に戻す操作以外は完全に実装依存
627 名前:604 mailto:sage [2005/05/22(日) 09:57:53 ] 「5.2.10 Reinterpret cast」の真意は、整数型にキャストし、演算後の《変更された値》をポインタにキャストし戻したとしても、それはポインタとして無効であるということだけだと思うぞ。 一例を挙げると、配列の特定要素を指すポインタを整数型に変換した後、インスタンスオブジェクトのサイズ分だけ値を加算し、ポインタ型に戻したとしても、次の要素へのポインタにはならないぞ、、、という。 Magic listにおける A-B-C という例において、Bに保存されている値はAのアドレスとCのアドレスを特定のルールで「エンコード」しただけの整数値であり、デコードすることにより元々のポインタ値を復元することが可能なはず(てーか復元できなければ意味はない)。 このため、上記の§5.2.10の規則には抵触しないと思うが? むしろ「A pointer *can be* explicitly converted to any integral type」と書かれている以上、そのことが保証されているとも取れる。 integral typeにして何の演算も許さず、元のポインタに戻すことしかできないのであれば、そもそもキャストする意味ないし。 まさかシリアライズするのか?、、、ってそれはあまりにも危険だしな。
628 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 10:18:14 ] >>626 ん?問題ないんじゃない? 同じポインタからは同じ整数になり、 同じ整数からは同じポインタになるっていう射影だよね。 この規格表のいいたいところは要するに、 アドレスが16違っている2つのポインタを、 整数に直した時も16違っているかどうかはわからないよ、 というだけの話じゃん。
629 名前:626 mailto:sage [2005/05/22(日) 10:20:55 ] >>627 >Magic listにおける A-B-C という例において、Bに保存されている値はAのアドレスとCのアドレスを特定のルールで「エンコード」しただけの整数値であり、デコードすることにより元々のポインタ値を復元することが可能なはず(てーか復元できなければ意味はない)。 >このため、上記の§5.2.10の規則には抵触しないと思うが? >むしろ「A pointer *can be* explicitly converted to any integral type」と書かれている以上、そのことが保証されているとも取れる。 5.2.10/5はポインタを整数にreinterpret_castした後,その整数値を「そのまま何の演算も行わずに」 元のポインタ型に再度reinterpret_castした場合,元のポインタ値に復元されることを保証するものです. 604さんのmagic_listでは排他的論理和演算を取るため「そのまま」ではないものの 5.2.10/5は明らかにreinterpret_castによるpointer <-> integerの1対1写像を保証しているものと 読めるため確かにそのとおりですね.626は621に対する指摘のつもりでしたが, いやはや指摘がまったく見当違いどころかむしろ621が正当である根拠になりえますね. これまた大変失礼しました. >>628 上に同じです.失礼しました.
630 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 12:18:47 ] magic list はネタとしては面白いが、現実には滅多に使われない データ構造だな。この手のネタは Hakcer's Delight とか Knuth センセの本を読むとイロイロ転がってるよ。 あと、現実のプログラミングだと、list に int 一個だけ入れるのも 珍しい気がする。手元のコードをいくつか見直してみたが、わりと 大きめの構造体を繋ぐか、スマートポインタを入れることが多い。 いずれにしてもポインタ二個分のメモリなんて誤差って感じ。
631 名前:デフォルトの名無しさん mailto:sage [2005/05/22(日) 13:39:00 ] 珍しいかどうかは、ともかく メモリ云々行ってた奴は、たぶん初心者だから 初心者の戯言を、あまり真に受けないほうが
632 名前:デフォルトの名無しさん mailto:sage [2005/05/23(月) 09:43:55 ] 結論はvector使え、でいいのか?
633 名前:デフォルトの名無しさん mailto:sage [2005/05/23(月) 09:54:29 ] >>632 いい
634 名前:デフォルトの名無しさん mailto:sage [2005/05/23(月) 12:40:40 ] magic list は所詮オナニー
635 名前:デフォルトの名無しさん mailto:sage [2005/05/23(月) 18:35:46 ] ここはジェネリックプログラミングの話題じゃないのか?
636 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 00:13:26 ] >>635 テンプレートの話題ですよ。尤も、スレタイも読めないなら このレスも読めない可能性、大。
637 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 03:37:35 ] 暇つぶしに作ってた、ヘボコンパイラは出来上がったから 今度は、マジックリストクラステンプレートでも作ってみようかな 作ったらほしい人いる?
638 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 08:09:05 ] >>637 興味はある
639 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 09:47:05 ] 学術的な興味なら。 ソースより測定結果をみたい。listやvectorとの比較つきで。
640 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 15:44:00 ] というか作りかけてる・・・
641 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 22:41:55 ] できたら >>639 もぜひ。
642 名前:デフォルトの名無しさん mailto:sage [2005/05/24(火) 23:45:11 ] >>640 637だけど、あなたに任せます
643 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 01:39:21 ] 小規模だけど多次元配列のポインタがどうしても必要で、newも使いたくないから std::vector<std::vector< ...> > とかで書いてみたんだけど、4次元ぐらいからコンパイル時間が凄くかかる。 ま、コンパイル時に何がおきてるか想像すりゃ当たり前といえば当たり前だし、 コンパイル時だけの問題なので気にしなきゃいいんだけど、 環境になるべく依存しないで(boostとかは使えないし、VC,gcc両方通す必要あり)、 効率の良い方法がありまつかね。std::deque使ってもかわらなさそうだし。
644 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 01:49:02 ] >>643 その「多次元配列」のインターフェースを必要最小限に絞って、 pimpl なり抽象インターフェースなりでコンパイル単位を分ける。 基本だな。
645 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 02:06:06 ] >>644 dクス。 pimplイディオムは詳しくないので、Exceptional C++でも読んでみまつ。
646 名前:640 mailto:sage [2005/05/25(水) 02:46:33 ] kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/458.txt 面倒だったのでBoost使いました.1.32.0が必要です.すいません. VC++7.1とGCC3.4.2(mingw)でコンパイル確認しています. 勢いだけで突っ走ったので激しく読みにくいコードで申し訳ないです. イテレータが安定じゃないのでsplice系がイテレータ返さないと 使い物にならないので,イテレータ返すようにしてます. std::listのインターフェースであと実装していないのはsortと演算子だけです. でも今日はもう気力残ってません.パフォーマンス測定もしかりです.おやすみなさい.
647 名前:デフォルトの名無しさん mailto:sage [2005/05/25(水) 04:02:34 ] void reverse() // throw() { head_ = decode(sentry_.code, head_); } 感動してしまった。
648 名前:デフォルトの名無しさん mailto:sage [2005/05/26(木) 03:43:21 ] kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/468.txt 微妙なバカチョンと例外飛んだときのバグを直しました.多分これで完璧なつもりです. ただ,相変わらずsortだけ面倒なので実装してないです. 指摘されていたこととは言え,このデータ構造イマイチ利点がぼやけてますね. 特にアラインメントの関係でノードのサイズが普通のリストのそれと 同じになってしまう(32-bitマシンでmagic_list<double>とか)場合もあったりで散々かも. 唯一,647さんが指摘されているように要素順の反転を定数時間でできるのが 大きな特色ですけれど,それがうれしい状況ってあるんでしょうか・・・.
649 名前:デフォルトの名無しさん [2005/06/06(月) 11:28:39 ] 質問です。 「具現化によって生成された実体」 = 「ユーザー定義ではないスペシャライゼーション」 という理解でいいの?
650 名前:デフォルトの名無しさん [2005/06/07(火) 22:08:43 ] "template テンプレート パラメータ"の意味が理解できないッス。 "Modern C++ Design" P11 の以下のコードなんですけど、 template <template <class> class CreationPolicy> class WidgetManager : public CreationPolicy<Widget> { ... } ここで template <class> に対して私の頭の中で シンタックスエラーが発生します 。 template<class T> // ノーマル template<> // 特殊化 template<class T=int> // デフォルト引数 template<class T, int=10> // 特殊化とデフォルト引数 というシンタックスは理解できています。 template <class> って何者? 誰か教えてください。
651 名前:デフォルトの名無しさん mailto:sage [2005/06/07(火) 22:12:38 ] 省略されてるだけ。 template <class /*T*/> class foo;
652 名前:デフォルトの名無しさん mailto:sage [2005/06/07(火) 22:27:41 ] >>651 サンクスです。とすると何らかの型を受け取るけど、 その型の情報は無視するよ、っていうことなんですね。 これをもとにもう一回読んでみます。
653 名前:デフォルトの名無しさん mailto:sage [2005/06/07(火) 22:32:56 ] >>650 int f(int i); int g(int); // これも脳内エラーが出るか?
654 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 00:28:08 ] >>650 例えば、 template< template<class T, class A> class Vector> struct hoge { typedef T value_t; }; typedef hoge<std::vector> hv_t; としても、この時点では”T"はまだ決まってないわけだから 名前付けても使えないのです。 無論、”Vector"もこのままでは使えません。 実際の使用には template< tempalte<class,class> class V> struct hoge { template<class T,class A> struct bind { typedef V<T,A> type; }; }; typedef hoge<std::vector> hv; typedef typename hv::template bind<int,std::allo..>::type のように使うことになりますね。
655 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 00:31:15 ] 補足ですが、 使えない == typedefできないということです。
656 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 00:41:11 ] >>654-655 とても650の理解を助けるとは思えない。
657 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 01:10:19 ] 間違ったことは言ってないが、質問の答えとしては完全にズレてるな。
658 名前:654 mailto:sage [2005/06/08(水) 01:22:29 ] >>656-657 この場合 >"template テンプレート パラメータ"の意味が理解できないッス。 と書いてあるところから、名前云々は関係ないと思うのですが・・
659 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 10:35:01 ] >>658 会話になってないな。もういいから喋るな。
660 名前:デフォルトの名無しさん mailto:sage [2005/06/08(水) 21:38:27 ] >>650 です。 皆さんありがとうございます。 >>654 さんのご意見もとても理解の助けになりました。
661 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:01:15 ] typedf templateってどうなったの?
662 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:13:16 ] template< template<class T, class A> class Vector> struct hoge { typedef T value_t; }; template<class B> typedef hoge<std::vector<B> > hv_t; typeof(hv_t<int>::value_t) i; みたいにtypedefの一文をテンプレート化できるんだっけ。
663 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:32:30 ] >>662 それはだめだろ。 template-templateパラメタのtemplateパラメタ(この場合T) に言及するのは意味的におかしい。
664 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:43:39 ] こうじゃないか? template <typename> struct hoge; template <template <typename, typename> class V, typename T, typename A> struct hoge<V<T, A> > { typedef T value_t; }; template <typename T> typedef hoge<std::vector<T> > hv_t; hv_t<int>::value_t i;
665 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:49:01 ] typedef templateを導入するなら変数templateや名前空間templateも欲しい。 と無責任に言ってみるテスト。
666 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 08:56:13 ] >>664 あーなるほど。C++よく分らないから適当に書いてみたんだけどそれなら理解できるw >template <template <typename, typename> class V, typename T, typename A> > struct hoge<V<T, A> > こうやって部分的特殊化で各パラメータ間の関係を表現できるのね。 >>663 >template <typename T> typedef hoge<std::vector<T> > hv_t; 問題はこの部分で、パラメータvector<T>の高階性(?!)を維持してくれるのかどうかってところかねえ。 >>665 変数templateとはどんなもんでしょ?
667 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 11:34:08 ] もしも変数テンプレートがあったとしたらこんな感じ? template <typename T> const T *NULL = 0; int *pi = NULL; char *pc = NULL; #include <cstdio> int main() { std::printf("%p", NULL<void *>); }
668 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 11:59:30 ] >>667 >int *pi = NULL; >char *pc = NULL; これを許すとまた規則が複雑になるな。
669 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 12:14:33 ] class null { public: template<typename T> operator T*() const { return 0; } }; const null NULL; int *ip = NULL; char *cp = NULL; printf("%p", (void*)NULL); でいいような気がす
670 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 12:16:52 ] 誰もそんな話ししてないわけだが
671 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 13:24:53 ] >>667 引数とるコンストラクターはどうなるんだ。
672 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 13:52:48 ] typedef template ムチャ欲しいな。
673 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:26:04 ] >>667 今のC++の型の取り扱いにあわせると template<typename T> const T *NULL = 0; は,右辺がリテラルの0でこれは型がintだからポインタ型に変換できず, Tをどの型でinstantiationすれば良いのか判断できずコンパイルエラーになる, っていう扱いが妥当だと思いますよ. もうちょい厳密に変数テンプレートを定義しようとすると, 結局,型推論のためのautoキーワードの拡張 auto a = b; // typename(b) a = b; の構文糖 と同じになると思います.Andrew Koenigあたりがこのautoキーワードの代わりに >>667 の構文を提案してたはず.
674 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:35:13 ] >>673 >>667 の代わりに、 template <typename T> struct wrap{static const T *null;}; template <typename T> const T *wrap<T>::null = 0; と書けることを考えると、今の扱いなら、 ・template <typename T> const T *NULL = 0; の時点では何も起こらない。 ・printf("%p" NULL<void *>); の点でインスタンス化が引き起こされ、void *const *を0で初期設定しようとし、成功。 が妥当じゃないのか?
675 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:50:45 ] >>670 そうでなくて、必要性が全く感じられないと言っている まともな利用例ぐらい出さないと
676 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 14:56:07 ] >>674 その使い方だと常に明示的にインスタンス化しないといけない (NULLを利用するたびに型パラメータを与えないといけない)わけですよね? それは利用範囲が著しく限られませんか?
677 名前:667 mailto:sage [2005/06/09(木) 15:03:10 ] ところで俺は変数テンプレートは全く要らないと思うんだけどな。 俺も669と同じようなのを考えたことはあるけど。
678 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 15:10:28 ] >>676 使い道がないのは同意。 ただ、仮に現在のテンプレートの延長で「変数テンプレート」なるものを定義するなら、 >>674 で言ったようになるはずだと思った。 >>673 のような機能を導入するなら別の名前・構文を考えるべきだと思う。
679 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 15:26:38 ] 型推論はされるとして、 NULLみたいに初期化子に使うとちょっと面白そうな… クラス階層のあるところでPTHREAD_MUTEX_INITIALIZERみたいなやつ。
680 名前:デフォルトの名無しさん mailto:sage [2005/06/09(木) 15:29:21 ] >>678 確かに「変数テンプレート」という名前は非常にまずいですね. ただ構文については既存のキーワード使うとするとこれぐらいしかないような気がします.
681 名前:デフォルトの名無しさん mailto:sage [2005/06/12(日) 15:01:48 ] アドビのオープンソースってど?流行ると思う? STL、boostを基に、ウィンドウをスクリプトから生成する画期的システム 仮想マシンを実現とか、内容は理解を超えていた (つД`) いわゆるチョット修正のときに威力を発揮すると思う SEはどんな些細なこともPGに要望しなけりゃならない PGは思いつきの修正のために仕事が増えるばかり だれか人柱になってください、やっぱアドビ待ちなのかな
682 名前:デフォルトの名無しさん mailto:sage [2005/06/12(日) 17:16:13 ] >>681 AdamとEve( ttp://opensource.adobe.com/ )のことか?なかなか 普及は難しいんじゃないかなぁ…
683 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 00:40:41 ] 質問です。 BCC 5.5上のテンプレートのバグはどのようなものが あるのでしょうか。 ・・・特に大きいタイプリストを渡すと、他の特殊化に指定 したクラスが別のクラスに化けるとか、そんなのないですか?
684 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 10:45:49 ] >>683 質問するときはやりたいこと、実際にやったことを書いた方が良い。
685 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 14:20:43 ] >>683 どういうバグかは知らんがboostが満足に使えない。
686 名前:683 mailto:sage [2005/06/13(月) 21:39:52 ] 自己解決しちゃいました。 経緯だけ説明しますと、Modern C++ Designのマルチメソッドを 自分の使いやすい形に改良して使っていたんです。で特殊化の 際タイプリストを template<..,class Head,class Tail>struct Dispatcher<...,Typelist<Head,Tail>,...>{ ...省略 }; と展開していて、6ほどの長さのタイプリストをわたしたところエラー吐かれました。 (5つまでは普通にコンパイル&動作しました) これを template<..,class TList>struct Dispatcher<...,TList,...>{ ...省略 }; としHeadにアクセスするときTList::Head,Tailにアクセスするときは TList::Tailとするようにしたら今度は何十の長さでもコンパイルできました。 前者のコンパイルの仕方にバグがあるんでしょうかね・・・
687 名前:デフォルトの名無しさん mailto:sage [2005/06/13(月) 23:51:10 ] BCCなんか使うなよ
688 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 17:45:57 ] もしかして、クラステンプレートのメンバ仮想関数って勝手に実体化される?
689 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 17:58:42 ] >>688 どんなコードでそう思った?
690 名前:688 mailto:sage [2005/06/14(火) 18:10:23 ] ものすごく単純化すると、 class base { public: virtual void foo() = 0; }; template <class> class derived : public base { public: virtual void foo() { std::cout << "呼ばれた\n"; } }; int main() { derived<int> d; static_cast<base&>(d).foo(); } こんな感じ。
691 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 18:24:16 ] >>690 それってderived<int>型の変数dを宣言したからderived<int>が実体化されているだけのように見えるが。
692 名前:688 mailto:sage [2005/06/14(火) 18:28:53 ] derived<int> が実体化されるのと derived<int>::foo が実体化されるのは別じゃないですか? クラステンプレートのメンバって呼ばれるまで実体化されませんよね?
693 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 18:31:57 ] >>688 規格では詳しくは規定されていないっぽい。 実際は ・derived<int>のインスタンスが宣言された ・derived<int>*からbase*の変換が行われた のいずれかをトリガとして、仮想関数をすべて実体化することになると思う。
694 名前:688 mailto:sage [2005/06/14(火) 18:40:33 ] >>693 サンクス。未定義ってことですか。 一応、明示的に実体化しておいたほうがよさそうですね。
695 名前:デフォルトの名無しさん mailto:sage [2005/06/14(火) 18:47:45 ] >一応、明示的に実体化しておいたほうがよさそうですね。 なんでそうなる? ついでに、「未定義」と「未規定」は違う。
696 名前:688 mailto:sage [2005/06/14(火) 18:50:17 ] ん? 規定はされていなくても、正常に動くことは保証されているってことですか?
697 名前:693 mailto:sage [2005/06/14(火) 18:57:55 ] 言い方が不正確だったな。 規格には、「メンバ関数は、その定義が必要とされるとき実体化される(意訳)」とある。 で、virtual関数については、いつ「定義が必要とされる」か正確に規定している部分が(俺の見た限りでは)なかった。 従って、virtual関数の正確な実体化のタイミングは規定されていないことになる。 それでも、「必要」になり次第実体化されることは保障される。
698 名前:688 mailto:sage [2005/06/14(火) 19:22:06 ] あー、なるほど。 規定されていないのは実体化されるタイミングだということですね。 どうもありがとうございました。
699 名前:デフォルトの名無しさん mailto:sage [2005/06/26(日) 18:25:16 ] int k = 0; for (vector< set<int> >::iterator it = v.begin(); it != v.end(); ++it) it->insert(k++); を boost::lambda か何かを使って for_each でシンプルに書けませんか? メンバー関数に bind する仕方がよく分からないんですが・・・
700 名前:デフォルトの名無しさん mailto:sage [2005/06/26(日) 19:33:36 ] >>699 typedef std::set< int > set_type; typedef std::vector< set_type > vector_type; void f( vector_type& v ) { using namespace boost::lambda; int k = 0; std::for_each(v.begin(), v.end(), (protect(bind((std::pair<set_type::iterator,bool> (set_type::*)(int const&))(&set_type::insert), _1, var(k)++)))(*_1)); } ○ boost::lambda か何かを使って ○ for_each で × シンプルに
701 名前:700 mailto:sage [2005/06/26(日) 19:49:39 ] メンバ関数に限らず、オーバーロードが絡むと lambda は使いにくいな。
702 名前:デフォルトの名無しさん mailto:sage [2005/06/27(月) 06:52:07 ] protect要るか? >>701 C++は名前が重なった場合の簡潔な指名定方法がないしね。 lambdaに限らず面倒。 typeofがBoostに入るそうだから、そのうち頑張って改善されるといいな。
703 名前:700 mailto:sage [2005/06/27(月) 07:50:29 ] >>702 こんな感じで変形していったが、途中のやつの エラーメッセージがひどくて(数100行ぐらい出る)、 何がまずかったのかよくわかってない。 × ((*_1)->*insert)(var(k)++) × bind(insert, *_1, var(k)++) ○ (protect(bind(insert, _1, var(k)++)))(*_1)
704 名前:702 mailto:sage [2005/06/27(月) 22:11:02 ] >>703 その3つの最初から間違ってるよ。 for_eachなんだから_1にはイテレータではなく参照が入る。よって _1をdereferenceする必要はない。 まあ同じなんだけど、俺ならオーバーロードが絡む場合は メンバ関数の特定を追い出すかな。 void hoge(vector<set<int> >& v) { typedef set<int> set_type; pair<set_type::iterator,bool>(set_type::*insert)(const int&) = &set_type::insert; int k = 0; for_each(v.begin(), v.end(), bind(insert, _1, var(k)++)); }
705 名前:700 mailto:sage [2005/06/28(火) 00:20:42 ] >>704 うわ、とんでもない勘違いをしていたよ。 ありがとう。
706 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 14:15:55 ] ttp://d.hatena.ne.jp/soleil/searchdiary?word=%2a%5b%c5%fd%b7%d7%5d ここに書いてあった struct Mean ってどう使うの? 例がないと分からない functorなのは分かったけど
707 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 14:27:54 ] int array[] = {1, 3, 5}; std::vector<double> v = ...; int ma = Mean<int *>()(array, array + 3); double mv = Mean<std::vector<double>::iterator>()(v.begin(), v.end()); こんな感じじゃないか?
708 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 16:19:10 ] for_eachにかけるものではないのね でも便利そう thx
709 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 16:25:40 ] >>707 のとおりにやってみたけど コンパイル通らなかったよ
710 名前:デフォルトの名無しさん mailto:sage [2005/07/05(火) 17:04:14 ] >>706 > 算術平均を求める Mean を書き直すと以下のようになる > (もちろん Sum も反復子を使うように変更してあることが前提) ちゃんとSumもコード書いた? んで、漏れなら、合計値(累積値)を求めるアルゴリズムaccumulateを使い 平均値は: void f(vector<double>& m) { double avg = accumulate(m.begin(), m.end(), 0.0) / m.size(); } のようにして求めるな。分散・標準偏差、RMSあたりも似たような実装ができる。
711 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 04:42:18 ] >>710 わざわざ関数にするのか? コードの大きさを抑えるのにはいいけど。
712 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 07:22:20 ] >>711 しない。入力が何で出力が何か明確にしたかったので、関数形式で書いただけ。 実際に関数にするなら、template、inline、引数にはconst、戻値の型を明記、あたりが必要です。 蛇足で糞コード晒す。 template <typename T> struct square : public binary_function<T, T, T> { T operator()(const T& lhs, const T& rhs) { return lhs + rhs*rhs; }; }; double ms = accumulate(m.begin(), m.end(), 0.0, square<double>()) / m.size(); double rms = sqrt(ms); double stdev = sqrt(ms - avg*avg);
713 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 08:07:25 ] STLは連続した、同じような事の繰り返し処理には滅法強いな。
714 名前:デフォルトの名無しさん mailto:sage [2005/07/06(水) 20:49:48 ] >>713 あなたの人生もSTLで簡単になりますよ。 void silly_life(life& your_life) { struct { static int daily(day& d) { d.nebou(); d.nichan(); d.onanu(); d.shigoto(); d.nichan(); d.onanu(); d.neru(); return 0; } }; std::for_each(your_life.begin(), your_life.end(), daily); } 久しぶりにtemplate見たよ。。。C#使いづれ〜。。。orz
715 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 00:00:05 ] それがSTLクオリティ。 語呂悪いな。
716 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 07:31:19 ] 速度が重要になるコードを書かなければなのですが、 やはりSTL経由の連続処理は、速度的に不利なんでしょうか? 一応自分なりに、次レスに書いたような実験をしてみたのですが、 プロファイル結果はSTL版hoge()が平均301msに対し、 シンプルなリストhage()の方が平均12msと、圧倒的な差に…。 今更自前リストなんて使うのは、考えただけで頭が痛くて。 なにかテストに落ちがないか、 或いはSTL版速度向上のための抜け道が無いか、教えて頂けないでしょうか。
717 名前:714 行制限のため、見づらくてすいません mailto:sage [2005/07/07(木) 07:35:09 ] #include <list> struct simple_list{ int val; simple_list* next; }; template <typename T> void hoge( T first, T last ){ int sum = 0; while( first != last ) sum += *(first++); }; void hage( simple_list* sl_first ){ int sum = 0; while( sl_first ){ sum += sl_first->val; sl_first = sl_first->next;} }; int main(){ std::list<int> listInt; for( unsigned long i=0; i < 100000; ++i ) listInt.push_back(i); simple_list* sl_first = new simple_list; simple_list* sl = sl_first; for( unsigned long c=0; c < 100000; ++c ){ sl->val = c; sl->next = new simple_list; sl = sl->next; } sl->next = NULL; hoge( listInt.begin(), listInt.end() ); hage( sl_first ); while( sl_first ){ sl = sl_first->next;delete sl_first; sl_first = sl; } return 0; }
718 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 07:51:04 ] >>716 プロファイルでは最適化は有効にしてる? 最適化しないと比較にならないし、最適化すると hoge(), hage() が sum を返してないので、最適化で処理自体が消えてダメかもしれない。 hoge の sum += *(first++); を { sum += *first; ++first } にすると、少し違うかもしれない。
719 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 07:51:41 ] >>716 最適化した? うちじゃ hoge(): 8.46567 ms hage(): 7.92051 ms くらいなんだけど 環境はg++ (3.3.5)
720 名前:716 mailto:sage [2005/07/07(木) 08:08:12 ] 我ながら非道い sl->next = NULL;を削って sl->next = new simple_list; を sl->next = (c != 100000-1) ? new simple_list : NULL; とでも >>718-719 最適化をすっかり忘れていました。 なぜだかsumを返すようにしてもhogeの方が消えてしまうのですが もう少し試行錯誤してみます。 いずれにせよ力づけられました。ホッとしています。 レスありがとうございました。
721 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 08:20:05 ] >>720 返すだけで戻り値を使ってないんじゃ、と消えるかもしれないな。 チェックもかねて、画面に値を出すようにすれば大丈夫じゃない? (そこまでやっても、ただの定数に置き換えてしまうコンパイラとかあるかもしれない。) 最終的にはアセンブリを吐かせて確認するといい。
722 名前:716 mailto:sage [2005/07/07(木) 08:25:49 ] 最適化無しで719さんの方法で15%ほど速く >>721 もしかしたらtemplateだったせいかも知れないです。インライン化されていたのかな。 templateを外したらhogeも出ました hoge: 5.579 ms hage: 5.313 ms (vc++6) 朝からお騒がせしました、お二人(三人?)に再度感謝です
723 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 08:31:10 ] その程度の処理だとlistは兎も角、vectorは普通の配列と全く同じ速度出るよ。 #つーか、gccでもVC++でもstlの有無で全く同じ(質の)コード吐くんだけどね。
724 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:13:33 ] >>723 VCだと vector>=配列 になるときもない?(誤差範囲内だけど) GCCは vector使うと少し遅くなる気がした。
725 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:23:22 ] その辺は具体的なコードを提示して比較でもしない限りなんとも言えないなぁ。 そもそも最適化で消えないコードでって条件になっちゃうし。
726 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:30:29 ] vectorのiteratorは大抵の処理系/STL実装で非デバッグ時には単なるポインタだろ。
727 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 18:34:16 ] >>722 ちなみに std::list が double-linked list だということは知ってるよな
728 名前:デフォルトの名無しさん mailto:sage [2005/07/07(木) 23:52:14 ] doubleじゃないSTLのlistを提示しない限りそのレスは無意味
729 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 00:55:24 ] >>728 おれは>727じゃないけど、なんで?
730 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 01:02:35 ] そういえばslistは標準じゃないんだな。 STLPortにはあるけど。
731 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 20:43:04 ] 次のようなコードがあるとします: struct base1 { base1(int x) {}; }; struct base2 { base2(int x, int y) {}; }; // IF<P,T,F>クラステンプレートは、Pが非0のときT、0のときFをIF::typeにtypedefする template <int N> struct derived : public IF<N,base1,base2>::type {}; このとき引数の数が異なるコンストラクタを持つ基底クラスをテンプレートで切り替え、 派生クラスのコンストラクタから、基底クラスのコンストラクタを呼び出したいのです: derived<1> d(0); // base1から継承し、コンストラクタは引数1 derived<0> d(0, 1); // base2から継承し、コンストラクタは引数2 基底クラスのコンストラクタを呼び出すときには、派生クラスの初期化リストを使います。 ところが、派生クラスのコンストラクタ初期化リストでは、基底クラスのコンストラクタ 以外呼べませんから、次のように多重定義できません: // Nが非0だとすると derived(int x) : base1(x) {}; derived(int x, int y) : base2(x, y) {}; // error! 基底クラスはbase1 このように基底クラスをテンプレートで替える場合に、うまく派生クラスのコンストラクタの 引数の数を調整するようなテクニックがあれば、ご教示いただけると幸いです。 また、異なるアプローチもあればコメントください。
732 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 20:50:10 ] 俺にはderivedをNの値によって特殊化する方法しか思いつかない。
733 名前:デフォルトの名無しさん mailto:sage [2005/07/08(金) 22:22:17 ] 試しにこう書いてみたら g++ 3.4.4 cygming special では通ったんだが。 derived(int x) : IF<N,base1,base2>::type(x) {} derived(int x, int y) : IF<N,base1,base2>::type(x,y) {}
734 名前:731 mailto:sage [2005/07/09(土) 02:41:09 ] >>732-733 レスありがとうございました。 >733の方法で、パパ、うまくできそうです。 続きがんばります!
735 名前:デフォルトの名無しさん mailto:sage [2005/07/09(土) 08:17:21 ] どうもネットの世界の「ご教示」とか「ご教授」って浮いた言葉だなぁ。
736 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 00:59:18 ] 実は初めてこの構文を知ったんだけどさ >ttp://www.comeaucomputing.com/techtalk/templates/#esprobs > >template <class T> >T foo(T blah) >{ > xyz object; > T someInt; > >// (略) > > someInt = object.mt<int>(99.99); // AA: ill-formed > someInt = object.template mt<int>(99.99); // BB: well-formed > > return someInt; >} ってなってて AA は ill-formed になってるんだけど、 object はテンプレートパラメータに依存してないんだから template をつけなくても問題ないと思うんだけど。実際 g++ 3.4.4 だと通るし、. の前をテンプレートパラメータに 依存するように書き換えるとエラーが出る。 規格参照箇所 14.2-4 > When the name of a member template specialization appears after . or -> in a postfix-expression, or after > nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a > template-parameter (14.6.2), the member template name must be prefixed by the keyword template. > Otherwise the name is assumed to name a non-template.
737 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 02:07:52 ] template <typename T> class Hoge { public: typedef std::vector<T> Container; typedef Container::iterator Iterator; private: Container v; }; と書いて、Hoge<int> hoge; とか呼ぶと、implicitなtypenameだと警告を言われます。 iteratorを表現するにはどのように記述すべきなのでしょうか。
738 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 02:09:19 ] >>737 gcc version 3.2 20020927 (prerelease) です。
739 名前:737 mailto:sage [2005/07/10(日) 02:11:47 ] www.tietew.jp/cppll/archive/10073 によると、 typename Container::iterator Iterator; と書くみたいですね。これって常識なのかしら。
740 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 02:27:11 ] >>739 その場合、typenameは必須。
741 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 02:36:16 ] 常識
742 名前:デフォルトの名無しさん mailto:sage [2005/07/10(日) 04:36:52 ] 当然
743 名前:デフォルトの名無しさん mailto:sage [2005/07/11(月) 10:24:40 ] >>739 特殊化があるC++では、Tが確定しないと型推論が困っちゃうんで、 typedef typename Container::iterator Iterator; って感じで。 typename Container::iterator Iterator; も可能。 Container<int> v; なら何とかなるはずだけど、explicitにtypenameしましょうという仕様。
744 名前:デフォルトの名無しさん mailto:sage [2005/07/16(土) 20:53:42 ] >型推論が困っちゃう そうなのか? Tが確定しないと、特殊化のあるC++ではstd::vector<T>::iteratorが typedefされた型名か、メンバ(メンバ変数・関数)かが分からないから コンパイラへのヒントとして型名であることを明示するのを義務付けてるんでは?
745 名前:デフォルトの名無しさん [2005/07/19(火) 22:11:08 ] 全然わかってないけど質問します。 テンプレートクラスの実装って全てヘッダーでやらないといけないんですか? .cppの方でやるとリンカーエラーが出てリンクできないのですが!? (全部ヘッダーにコピペしたら通った)
746 名前:デフォルトの名無しさん mailto:sage [2005/07/19(火) 22:14:53 ] 追加 だが、しかしそれをやると2重定義になる… どうすればいいんじゃーーーー
747 名前:デフォルトの名無しさん mailto:sage [2005/07/19(火) 22:20:05 ] >>745 テンプレートの定義をcppファイルに書きたければ、宣言と定義の両方にexportを付けるだけ。 しかしほとんどのコンパイラで使えない。(使えるコンパイラが全くないわけではない) というわけで普通はヘッダにインラインで全て書く。 ごく稀に明示的実体化が使われることはあるが。
748 名前:デフォルトの名無しさん mailto:sage [2005/07/19(火) 22:48:35 ] >>747 明示的実体化ってまさか、 template class c<bool>; template class c<char>; template class c<unsigned char>; みたいに延々と cpp ファイルに書いていくわけ?
749 名前:デフォルトの名無しさん mailto:sage [2005/07/19(火) 23:06:05 ] g++にはextern templateってのがあるね。
750 名前:デフォルトの名無しさん mailto:sage [2005/07/19(火) 23:11:50 ] >748 そゆこと。
751 名前:745 mailto:sage [2005/07/19(火) 23:17:21 ] やってみた>>747 make -k all g++ -Wall main.cpp Class.cpp -c g++ -Wall main.o Class.o -o a.exe main.o(.text+0x25):main.cpp: undefined reference to `Class<int>::Class[in-charge]()' collect2: ld returned 1 exit status make: *** [all] Error 1 ムリポ >>749 を含めて出直してくる。これはイマの私の頭ではいくら考えても答えが出ない。 本を読むかg++のマニュアルを漁るか…
752 名前:デフォルトの名無しさん mailto:sage [2005/07/19(火) 23:44:58 ] >>751 g++のinclude/bits/istream.tccより // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. #if _GLIBCPP_EXTERN_TEMPLATE extern template class basic_istream<char>; extern template istream& ws(istream&); extern template istream& operator>>(istream&, char&); extern template istream& operator>>(istream&, char*)
753 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 19:33:12 ] template <class T> class foo; template <class T> class baa{ friend foo; int n; public: baa() : n(777){} }; template <class T> class foo : public baa<T>{ int hoge; public: void set_val( baa<T>& arg ){ hoge = arg.n; } }; int main(){ baa<int> b; foo<int> f; f.set_val( b ); return 0; } インデントが全角スペースですいません これだとarg.nにアクセス出来ないのですが、間違っている場所を教えて頂けないでしょうか friend foo; が、やっぱり template <class T> friend foo; なんでしょうか
754 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 19:45:24 ] >>753 g++ でコンパイルすると、 :4: error: ISO C++ forbids declaration of `foo' with no type :4: error: `foo' is neither function nor member function; cannot be declared friend まぁそれは置いとくとして、 friend class foo<T>; で通ったよ。
755 名前:753 mailto:sage [2005/07/23(土) 19:59:42 ] >>754 やっぱりclass指定しますよね 書き込む前にチェックしたサイトで、指定が無かったので、自分が間違っていたのかと そうか、再度template <class T>付けるのは馬鹿でした。 VC6なので、Tが同じじゃなかったらアウトだったかも・・・良かった。 本当に助かりました。コンパイルまでして頂いてすいません。ありがとうございました。
756 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 20:13:13 ] baaっての…なんかプログラムがアホっぽくなるな。
757 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 22:22:39 ] >>755 friend かどうかっていう問題なのか? baa<T>::n が private か protected/public かどうかっていう問題では?
758 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 22:47:57 ] >>757 vtableを避けるための小細工なんです 眉をしかめる人が多いと思いますが、自分しか使わないのでお見逃しを
759 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 23:36:56 ] >>758 よくわからないな。>>753 のを template <class T> class baa{ protected: int n; public: baa() : n(777){} }; とすると VC6 だと vtable に関して状況が変わるの?
760 名前:デフォルトの名無しさん mailto:sage [2005/07/23(土) 23:51:14 ] 753がprotectedを知らなかったというオチ?
761 名前:デフォルトの名無しさん mailto:sage [2005/07/24(日) 00:21:24 ] >>759 失礼、深読みしすぎてました。 しかしすいません、そうなると>>757 で頂いたレスの意図が分からないです。 protectedすると、引数で他のbaaを受け取ったとき、nにアクセス出来るのでしょうか。
762 名前:760 mailto:sage [2005/07/24(日) 00:40:00 ] 753のコードでは、bar<T>::nがprotectedならfoo<T>::set_valの中でarg.nにアクセスできると思っていたがそうではなかったようだ。 スマソ
763 名前:デフォルトの名無しさん mailto:sage [2005/07/24(日) 01:03:17 ] >>761 アクセスできると思ってた。けど間違ってたのなら失礼。 ・基本 class から 派生 class を public 継承したとき、 ・基本 class の protected member である n について、 ・派生 class から this の n にアクセスできる。 ・派生 class から this 以外の n にアクセスできない。 ということかな?も一回勉強しなおそ。 ・ある class の private member である n について、 ・その class から this の n にアクセスできる。 ・その class から this 以外の n にアクセスできる。 というのは間違いないと思うんだけど。 あと自分の VC7 は、これに関して template class かそうでないかによって コンパイル結果が違うのもよくわからない。
764 名前:デフォルトの名無しさん mailto:sage [2005/07/24(日) 02:17:54 ] 勉強しなおした。>>763 は間違い多数につきスルーよろしく。失礼しますた。
765 名前:デフォルトの名無しさん mailto:sage [2005/07/28(木) 18:38:46 ] Compile-time if で型でなく値を返すにはどうすればいいのでしょうか? int v= boost::mpl::if_c< (sizeof(T) <= sizeof(double)), 10, 20 >::Value はだめでした
766 名前:デフォルトの名無しさん mailto:sage [2005/07/28(木) 19:41:12 ] >>765 boost::mpl::int_ を使って、型にマップすればいい。
767 名前:デフォルトの名無しさん mailto:sage [2005/07/28(木) 19:56:38 ] >>765 struct R0 { enum {value = 10}; }; struct R1 { enum {value = 20}; }; template <typename T> int func () { typedef typename boost::mpl::if_c <(sizeof (T) <= sizeof (double)), R0, R1>::type Result; return Result::value; }
768 名前:デフォルトの名無しさん mailto:sage [2005/07/29(金) 10:42:43 ] template<CONTANER> class CmyContaner { typedef CONTANER::iterator iterator_type; }; としたらコンパイル通らなかったんですが、 CONTANER::iteratorはできないってことなのでしょうか?
769 名前:デフォルトの名無しさん mailto:sage [2005/07/29(金) 11:35:24 ] >>768 -typedef CONTANER::iterator iterator_type; +typedef typename CONTANER::iterator iterator_type;
770 名前:デフォルトの名無しさん mailto:sage [2005/07/29(金) 15:37:41 ] そのままじゃ型名かメンバ変数かわからんからね。 > CONTANER 北斗の拳の主題歌を思い出すスペルミスだな。
771 名前:デフォルトの名無しさん mailto:sage [2005/07/29(金) 16:46:27 ] >>768 ここもだね -template<CONTANER> +template<typename CONTANER>
772 名前:デフォルトの名無しさん [2005/07/30(土) 08:40:48 ] template<Functor> class MyMethod { public: Functor f_ MyMethod(Functor f):f(f_) {} value() { f_(10); } }; class MyClass { public: struct MyFunctor{ operator()(int a) { std::cout << a; }myFunc; //MyMethod<MyFunctor> myMethod(myFunc);//コンパイル通らない MyMethod<MyFunctor> myMethod(MyFunctor);//なぜかコンパイル通る value(){ myMethod.value();//左側がクラス 構造体 共用体でありません と怒られる } }; クラスの中でfunctorを定義したら動かなくなりました。 回避方法はないのでしょうか?
773 名前:デフォルトの名無しさん mailto:sage [2005/07/30(土) 09:48:49 ] >>772 >クラスの中でfunctorを定義したら動かなくなりました。 クラスの外でfunctorを定義したらそれ動く?
774 名前:デフォルトの名無しさん mailto:sage [2005/07/30(土) 13:47:17 ] >772 とりあえず } が 1 個足りない。 } myFunc; の前に 1 個ある、でいいのか? >MyMethod<MyFunctor> myMethod(MyFunctor); これだと MyFunctor 型の引数をとり、MyMethod<MyFunctor> 型を返すメンバ関数 myMethod を 宣言しているんじゃまいか? >//MyMethod<MyFunctor> myMethod(myFunc);//コンパイル通らない なんでメンバ変数を宣言してるのに初期化しようとしてるの? MyMethod<MyFunctor> myMethod; MyClass() : myMethod(myFunc) {} じゃねーのか?あと↑だと myFunc との初期化順序が問題になる場合があるかも。 今回の場合、MyClass() : myMethod(MyFunctor()) でいいような気もするが。
775 名前:772 [2005/07/30(土) 14:59:26 ] すみません } が1つぬけてました。 template<Functor> class MyMethod にclass の外で定義したfunctorを使うと 意図したとうりの動きをすることを確認しています。
776 名前:デフォルトの名無しさん mailto:sage [2005/07/30(土) 15:06:57 ] >>775 >class の外で定義したfunctorを使うと >意図したとうりの動きをすることを確認しています。 本当に? コピペにかなりミスがあると思うよ MyMethod::value() MyClass::MyFunctor::operator()(int a) の返値の型は? もし本当に動くなら処理系を教えてね
777 名前:776 mailto:sage [2005/07/30(土) 15:09:07 ] たぶんこんなことしたいのかな template <typename Functor> struct MyMethod { Functor f_; MyMethod (Functor f): f_(f) {} void value () {f_ (10);} }; struct MyClass { struct MyFunctor { void operator () (int a) { std::cout << a; } } myFunc; MyMethod <MyFunctor> myMethod; MyClass (): myFunc (), myMethod(myFunc) {} void value() {myMethod.value();} };
778 名前:デフォルトの名無しさん mailto:sage [2005/08/02(火) 22:23:20 ] template<X> class CHoge {public: CHoge( X= typeof(x) ) {} }; なんてできないの? 自動で型判別してほしい。 自動判別した型を使ってCompile-time Ifもできるとさらにいいんだけど
779 名前:デフォルトの名無しさん mailto:sage [2005/08/02(火) 23:18:35 ] >>778 >自動で型判別してほしい。 >自動判別した型を使ってCompile-time Ifもできるとさらにいいんだけど これらはできるけど 例で何がしたいのかさっぱり分かりません
780 名前:デフォルトの名無しさん mailto:sage [2005/08/05(金) 23:15:18 ] template< ArrayType > function( ArrayType array) { Compile-time If (ArrayType はポインタの配列?) { int a= array[0]->value; }else{ int a= array[0].value; } こんなことがしたい
781 名前:デフォルトの名無しさん mailto:sage [2005/08/05(金) 23:30:47 ] type_traitsでいいんじゃないの?
782 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 00:52:15 ] 個人的には値の配列とポインタの配列を静的多相に扱おうとする行為そのものに 異議を申し立てたい.
783 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 02:36:31 ] 次のようなコードが、Visual C++では通るけどGCCでは通りません。 オブジェクトの名前と番号の型を保持する構造体を用意 template<class S,class I> struct Types { typedef S String; typedef I Integer; }; この定義を受け取って型を定義するベースクラスを作成 template<class T> struct Base { typedef typename T::String StringType; typedef typename T::Integer IntegerType; }; そして、これを利用するサブクラスを作成。 template<class T> struct Derived : public Base<T> { StringType name; //!< ここでコンパイルエラー IntegerType number; //!< 同様 }; typedef Types<std::string,int> StdTypes; Derived<StdTypes> derived;
784 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 02:38:23 ] 続き 以下のように書けばGCCでもコンパイルは通ります。 typename Derived::StringType name; typename Derived::IntegerType number; こんな面倒な書き方しかできないなら、 わざわざベースクラスにtypedefした意味がないんですが 何かいい方法ありませんか?
785 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 02:58:54 ] >>783-784 Base の定義中に typename が必要な理由を知っていれば、無理だと予想が付くだろうに。
786 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 07:54:33 ] >>783-784 俺だったら Base::Stringと書けないか Derivedの中にusing Base::String;と書けばStringが使えないか の2つをまず試してみる。これでできるかどうかはもちろんしらんが。
787 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 09:04:33 ] Baseを使うなら、 typename Base<T>::StringType name; typename Base<T>::IntegerType number; こうなるから、これこそ、 > わざわざベースクラスにtypedefした意味がない ので、>>784 のやり方が良いだろう。 VC++もそのうち>>783 は駄目になることでしょう。
788 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 09:32:41 ] >>784 それVC7.1のバグらしい。 面倒見が良すぎて、typenameを本来ならば書かなければならない 所を、曖昧さがない場合は無くても通してしまう。 VC7.1でもちゃんと typename は書くべき。
789 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 12:59:29 ] このスレの難読コードをみて おれにとて C++はなかたことになた
790 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 13:03:53 ] そんなだから、未だに君にとってこの程度が「難読コード」なんだよ。
791 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 13:07:40 ] 俺もtemplateのコードは可読性が低いと思うよ 唯一の弱点だな
792 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 13:32:35 ] テンプレートとC++「本体」って明らかに別の言語だよな。 概念の異なる2つの言語が混在してるんだから、 可読性が低いのは当たり前。
793 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 15:19:32 ] >>792 じゃあどういう構文にすればいいよ?
794 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 19:15:56 ] 構文の話なのかな。
795 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 19:21:27 ] >>784 template<class T> struct Derived : public Base<T> { typedef Base <T> Base_; typedef typename Base_::StringType StringType; typedef typename Base_::IntegerType IntegerType; StringType name; IntegerType number; };
796 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 20:27:48 ] >>795 意味無いじゃん。
797 名前:神゜ mailto:sage [2005/08/06(土) 20:49:53 ] そろそろ俺の出番か?
798 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 21:04:29 ] >>784 ベースクラスがテンプレート依存でなければ StringType,IntegerType は見えるが、そうでない場合は 795 のように書く必要がある。 実はずっと前の GCC で VC7.1 みたくエラーにならない時期が あったんだが、バージョン上げたらエラーになったんで仕様を 確認したことがあったのを思い出したよ。
799 名前:デフォルトの名無しさん mailto:sage [2005/08/06(土) 23:17:54 ] >>798 2.95あたりは確かそうだったね
800 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 16:48:53 ] template<class A> struct Foo { template<class B> struct Bar { }; }; このBarだけを特殊化するのって、GCCでは template<>template<> struct Foo<int>::Bar<int> って書かなきゃならないんだね。 VC++7.1では template<> struct Foo<int>::Bar<int> で通るんだけど、これはバグなのかな?
801 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 16:55:26 ] >>800 どっちが規格に準じてるかによるね
802 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 17:00:26 ] >>800 14.7.3.17 より "If the declaration of an explicit specialization for such a member appears in namespace scope, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized." template<> template<> ... と繰り返すのが正解っぽい。
803 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 17:10:09 ] >>800 gccを信じてそちらに合わせておけ。
804 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 17:27:08 ] >>800 gccのバージョンは何? g++ 3.3.5 だとそれ両方とも通るんだけど 新しいのは通らないのかな?
805 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 18:19:07 ] template <class T> typename enable_if<boost::is_integral<T>, void>::type foo(T t) {} で関数を定義したりできないのはわかるけど これでclassのコンストラクターを定義したりしなかったりを決めると コンストラクターに戻り値が定義されています と怒られる。何か方法ないのでしょうか? template <class T> class A{ typename enable_if<boost::is_integral<T>, void>::type A(T t) { } }
806 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 18:44:57 ] >>805 SFINAEは戻り値の型でやる方法と(デフォルト)引数の型でやる方法の2通りできて, コンストラクタの場合は戻り値の型を指定できないですから引数の型のほうでやります. template<class T> class T{ A(T t, typename enable_if<boost::is_integral<T> >::type * = 0){} }; こんな感じで.逆に演算子関数の場合は余計なデフォルト引数を指定できないので 戻り値型で,という感じになると思います.
807 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 22:38:01 ] enable_ifが何をするもんなのか、未だにわかんねえ。 てか、何年英語の勉強してもboostのドキュメントさえ読めない俺ってすげえよ。 よっぽど英語の才能が無いんだな。
808 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 22:41:04 ] テメェは自己紹介がしたいだけだろ 分からねぇんだったらイチイチ出てくんな
809 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 22:50:40 ] >>807 SFINAEによるオーバーロードセットのコントロールを簡単に 行うためのユーティリティ。 英語分からなくてもC++分かるんならひたすらソース詠めば 何となく見えてくる、かもよ。
810 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 22:53:46 ] >>808 なにキレてんのキミ。 相手以上の駄レス書いてたら意味無いのに。
811 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 22:59:07 ] 駄レスとかいってたら、ほとんどがそうだろw
812 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:00:10 ] ほとんどがそうならなおのこと 突然特定のレスにキレる理由が無いよ。
813 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:03:27 ] 自己顕示欲丸出しの厨房がウザイだけだろ まあ、どこにでもいるからいちいちキレるのもどうかと思うが
814 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:16:33 ] キレて説教するほうがよっぽど自己顕示欲激しいと思う。 世に言う自爆ですな。アホくさ。
815 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:17:52 ] www.boost.org/libs/utility/enable_if.html ここの「1.2 Background」は、何が問題だって言ってるんですか?
816 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:20:01 ] 説教がどう自己顕示欲につながるんだ??
817 名前:デフォルトの名無しさん [2005/08/07(日) 23:22:14 ] >>814 ワロス
818 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:29:27 ] >>816 キレるたびにいちいちスレ違いの書き込みするような奴が 自己顕示欲薄いって言い張る気?
819 名前:デフォルトの名無しさん [2005/08/07(日) 23:30:34 ] enable_ifがわからんってののどこが自己顕示欲に繋がるのかもわからんけどな
820 名前:デフォルトの名無しさん [2005/08/07(日) 23:30:49 ] >>818 藻前もキレてるじゃん あと煽り耐性なさ過ぎ いい加減スルーしろよ
821 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:31:47 ] >>815 いや,そこの部分は別に何かが問題だなんて書いてないです. 単にSFINAEというのがどう機能するか(そしてなぜそのような機能が必要なのか) を説明しているだけです.
822 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:32:15 ] 816が煽りには見えないけどなあ。 普通にズレてるだけで。
823 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:32:55 ] >>815 あっと,「もしSFINAEがなければこういうことが問題だよね」というのは書いてますけれど.
824 名前:デフォルトの名無しさん [2005/08/07(日) 23:35:03 ] >>822 分かったからもう出てくんな
825 名前:デフォルトの名無しさん mailto:sage [2005/08/07(日) 23:40:11 ] 本日の推奨NG 「。」「顕示」「煽り」「キレ」 すっきりして(・∀・)イイ!!
826 名前:デフォルトの名無しさん mailto:sage [2005/08/08(月) 02:07:36 ] expressional template VC.net2003だと、ちょっと複雑な式を書いただけで コンパイル通らない。 そういうものなの? gccなら通るのかな
827 名前:デフォルトの名無しさん mailto:sage [2005/08/08(月) 02:12:44 ] >>826 その「ちょっと複雑な式」とやらを晒すとレスが付くかもしれない。
828 名前:デフォルトの名無しさん [2005/08/08(月) 03:35:21 ] >>826 現存する如何なるコンパイラでも通らない程複雑(広義の)なコードに問題ありに100円。
829 名前:デフォルトの名無しさん mailto:sage [2005/08/08(月) 04:40:19 ] ネストが17超えるとか?
830 名前:デフォルトの名無しさん mailto:sage [2005/08/08(月) 15:16:31 ] いろんな要素が混じってるので必ずしもexpressional templateが 原因でないのかもしれないけど boost::numeric::ublas::matrix & A(){return A_ } boost::numeric::ublas::matrix & B(){return B_ } B() = prod( A(), A())*3 + B() + .... こんな感じかな.全部はさらせないのですまそ
831 名前:デフォルトの名無しさん mailto:sage [2005/08/09(火) 01:41:27 ] >>830 エラー貼ったがいいよ もし膨大なら 再現するコンパイル可能な最小のコードを貼って
832 名前:831 mailto:sage [2005/08/09(火) 01:45:25 ] >コンパイル可能な おっとコンパイルは通らないのか >あなたがコンパイル通らないことを理不尽に思う に訂正 ようするにテストする側の身になってコードを 貼ってください
833 名前:デフォルトの名無しさん mailto:sage [2005/08/09(火) 11:45:51 ] >>830 >こんな感じかな.全部はさらせないのですまそ じゃあ、他の人にエラーの原因を調べてもらうのも諦める事ですな。 証拠不十分なまま、証言台に立つような物ですぞ。
834 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 08:39:28 ] だれもいない
835 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 20:28:20 ] ホントにだれもいないのかよ
836 名前:デフォルトの名無しさん [2005/08/20(土) 20:39:26 ] いねーよ
837 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 20:40:28 ] 質問やら話題があれば人は自然と集まってくる。
838 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 20:52:57 ] おまえら ”てんぷれーと”にだまされてないか? ”しーぷらぷらのてんぷれーと”って結局あれだよ。 中途半端。 そう中途半端。 LISPに比べたら。 全然読み易くならない。 いろんな括弧であふれてLISPの方がまだサルのように読みやすい。 まあここにタムロしてるおまえらの言い分は判ってるよ こうだろ、静的カタカタ型が重要なんです! LISPじゃすぴーどでないよプププ とかな。 ばーか。 カタなんかより柔軟性なんだよこのご時世はよ カタカタうるせーのなんのって、笑うわ。 C++考えた奴みたいにハゲろ 全員
839 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 20:59:39 ] 確かに、「ネイティブコード吐く言語じゃないと速度が」 とか必死に言ってる奴に優秀なプログラマはいないな。
840 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 21:10:42 ] しーぷらぷらの処理系。 てんぷれーとバグだらけ。 笑うわ。 いったい何年てんぷれーとやってんだよ おまえらがべんだーの修正待つあいだに おれLISPで新しいマクロどっさり作る 生産性バカたけぇーわLISPはよ LISPはカタないからすぴーどでないよプププて、 そりゃ頭がかてえ証拠だな。 そんな奴は引退したほーがいいんじゃねーかなあ LISPにカタないなら組み込めよ、ハゲども ぶーとすとらっぷとか考えろよ わかるか?ぶーとすとらっぷって。 しーぷらぷらにはそんながいねんはないかもなあ。 最適化なんかやりやすいなーすいすいいけるぜ こんすの海の中にいると不満なんてすぐ解消する それがLISP。 まあ頭のかたいカタカタ野郎は やっぱりC++考えた奴みたいにハゲろ 全員
841 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 21:16:51 ] >>839 よりは優秀だけどね。
842 名前:マイク ◆yrBrqfF1Ew mailto:sage [2005/08/20(土) 21:31:32 ] C++をしーぷらぷらなんて言うのは無能。
843 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 21:59:52 ] C++でLisp系の俺言語&処理系作るのが最近の俺の趣味なんだが、 なんかこいつの仲間と思われたくないな、恥ずかしくて。
844 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 22:59:08 ] >>842 シープラスプラス? それともシーたすたす?
845 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 23:33:28 ] しーいんくりめんと
846 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 23:43:58 ] C++ 後置ということは、まだ本当のC++にはであてないわけだ
847 名前:デフォルトの名無しさん mailto:sage [2005/08/20(土) 23:45:24 ] C++には出会えている ++Cに出会えてないだけ
848 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 00:37:45 ] 838は、C++のテンプレートが読みにくく、 コンパイラのバグのことも分かっていて、 C++作った人物についても詳しいようだな
849 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 00:48:03 ] Schemeの純粋指向にはあこがれるけど、Lispはどうでもいいや。 継続は面白いな。 >LISPはカタないからすぴーどでないよプププて、 型が無いと遅くなるつうのは初耳ですが、どこの情報?
850 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 01:06:13 ] >>849 VBのバリアント型みたくデータ側に型情報があるから オブジェクトを参照するたびに動的な判定が毎回必要ってことだよ。 型判定に値の取り出しとか最低でもCの3倍以上のコストが掛かる。 Rubyが遅いのもこれがかなり影響してる。
851 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 01:09:17 ] でも日本語は不自由なようだ。
852 名前:851 mailto:sage [2005/08/21(日) 01:09:45 ] >>838
853 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 01:25:23 ] > オブジェクトを参照するたびに動的な判定が毎回必要ってことだよ。 随分ダサい実装ですね。
854 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 01:41:07 ] そのダサイ実装を越えたところに桃源郷が
855 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 01:41:43 ] ももげんごう?
856 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 12:12:15 ] ももげんごう(←なか変換できない)
857 名前:デフォルトの名無しさん mailto:sage [2005/08/21(日) 14:42:55 ] 桃源郷=Xanadu キサナドゥ
858 名前:デフォルトの名無しさん mailto:sage [2005/08/22(月) 00:38:44 ] >>850 正直、有名なコンパイラならそんなださい実装は少ないよ。 Common Lispには型指定の構文があるくらいだし。
859 名前:デフォルトの名無しさん mailto:sage [2005/08/23(火) 09:18:30 ] 数値計算したい人は 速度気にしないならlistでなくてMatlab使う
860 名前:デフォルトの名無しさん mailto:sage [2005/08/23(火) 15:06:35 ] >>858 CLOS基地外氏ね スレ違いだし
861 名前:デフォルトの名無しさん mailto:sage [2005/08/23(火) 15:34:43 ] だれもいないからとか言うから
862 名前:デフォルトの名無しさん mailto:sage [2005/08/23(火) 16:29:46 ] 人稲杉なので、チラシの裏 boost::bind は、bind( f, _1, _2, a, b, _1 ) を行うことで、 func::return_type ( A1 & a1, A2 & a2 ) というファンクタを返すけど、 この _1 や _2 を、_decimal や、_text、_float のような書式指定プレイスホルダに 置き換えて、以下のようにすれば、タイプセーフな printf が出来るなと 考えたことがあった。 function< void( int ) > f = format( cout, "a = ", _hex, endl ); // ↑ cout << "a=" << %x << endl; と同じ事を行うファンクタを返す。 f( 10 ); // cout << "a=" << hex << 10 << endl; f("aaa"); // コンパイルエラー 上の形とは違うけどその思想に基づいて実際に作ってみたことがある。 でも結局実用では (w)sprintf しか使わなかった。勉強にはなったけどね。 template プログラミングは楽しいけど、冷静なるとしなくていいことまで テンプレート化してたりしていることがあるので気をつけないと。
863 名前:デフォルトの名無しさん mailto:sage [2005/08/23(火) 17:12:40 ] >>862 > 冷静なるとしなくていいことまでテンプレート化してたりしていることがある 昨夜、そんな関数テンプレートを必死で非テンプレート関数に直してた・・・。 数日前に必死で関数テンプレートにした箇所だったのだけど・・・。
864 名前:デフォルトの名無しさん mailto:sage [2005/08/24(水) 12:24:27 ] template<typename X_TYPE> void xxx(X_TYPE x) {} として型の自動認識の手間減らしは多用するな
865 名前:デフォルトの名無しさん mailto:sage [2005/08/24(水) 13:32:40 ] そうね。時々やる。いっそのこと型を書くのはオプションにして MLみたいに型推論してくれればいいのにと思う。
866 名前:デフォルトの名無しさん mailto:sage [2005/08/24(水) 17:50:00 ] C++ 0xだとそんな機能が追加されるとかされないとか。
867 名前:デフォルトの名無しさん [2005/08/28(日) 09:36:27 ] テンプレートがちんぷんかんぷんでまったく理解できない私に 理解できるようになる方法を教えてください。まじで。
868 名前:デフォルトの名無しさん mailto:sage [2005/08/28(日) 11:02:49 ] 引数の型を使うときに決められるんだよ。
869 名前:デフォルトの名無しさん mailto:sage [2005/08/28(日) 11:35:27 ] >>867 騙されたと思ってstd::min()でも使って味噌。
870 名前:デフォルトの名無しさん mailto:sage [2005/08/28(日) 13:22:51 ] せめてstd::vector くらい使わないとありがたみ沸かないだろう。
871 名前:デフォルトの名無しさん mailto:sage [2005/08/28(日) 18:04:02 ] >>867 つ[C++ Templates(英文)]
872 名前:デフォルトの名無しさん mailto:sage [2005/08/29(月) 06:58:30 ] STL バンザイ
873 名前:デフォルトの名無しさん mailto:sage [2005/08/29(月) 21:56:02 ] STLとboostが無かったら俺C++使いつづけて無かったよ。
874 名前:デフォルトの名無しさん mailto:sage [2005/08/29(月) 22:30:29 ] 俺もそうだ。
875 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 00:21:09 ] 会社でtemplate使うなって言われたんだけど… 何故?
876 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 00:24:13 ] 会社で使いこなせるヤシがいないからと邪推
877 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 00:31:06 ] 代わりにLISP使え もっと困るかもな へへ
878 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 03:19:35 ] >>875 それは、あなたが馬鹿だからです。
879 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 03:26:37 ] お前だけは使うなって言われたなら そうかもしれないけどさ
880 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 09:13:41 ] >>875 まともな会社にうつるべし
881 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 09:55:32 ] >>875 会社に聞け。 ここで聞くようなやつは>>878 に決定。
882 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 10:02:04 ] >>881 なんでそんな必死にこの話題にフタしたがるの? コンプレックスでも刺激された?w
883 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 11:09:31 ] >>882 頭、大丈夫か?
884 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 14:45:37 ] VC6のプログラム保守してるとかじゃないのか>875
885 名前:デフォルトの名無しさん mailto:sage [2005/09/03(土) 22:33:39 ] >>883 大丈夫だよ。 質問に答えられない誰かさんの頭は大丈夫じゃないみたいだけど。
886 名前:デフォルトの名無しさん mailto:sage [2005/09/04(日) 03:17:12 ] ・移植性重視 ・扱える開発者が少ない or メンテする人が固定とは限らない のどっちかだろうねえ 後者の事情のほうが多いと思うけども
887 名前:デフォルトの名無しさん mailto:sage [2005/09/09(金) 02:16:23 ] 管理職の団塊世代が、ピュアなC以外理解できないとか
888 名前:デフォルトの名無しさん mailto:sage [2005/09/09(金) 22:28:28 ] 名前空間→記述が冗長すぎる テンプレート→制限が多すぎる クラス→継承が可読性を悪化させる その他→コンパイル時間が長すぎる
889 名前:デフォルトの名無しさん mailto:sage [2005/09/09(金) 23:39:18 ] C++→俺が解からない
890 名前:デフォルトの名無しさん mailto:sage [2005/09/09(金) 23:45:15 ] 俺が解からない→みんなも解からない
891 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 02:04:02 ] >>886 >移植性重視 templateって移植性下がるの?
892 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 02:33:11 ] 例えばGCCと心中するつもりならGCCで動けばOKって人もいるでしょ
893 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 02:46:27 ] >>891 ある程度ISO C++に準拠したコンパイラがない環境には移植できなったりだとか。
894 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 03:16:30 ] 少なくとも、vc7.1とgccの両方で動くテンプレートくらい書けないと 話にならないと思うけど。
895 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 12:53:08 ] VC7.1とgcc3.3以降で動くテンプレート書くのは簡単だろ、どっちもほぼ100%標準準拠なんだから。 むしろVC6とかgcc3.2とかで動くか動かないか判断する方が難しいと思われ。
896 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 13:14:28 ] >>895 VC6とgcc3.2以前はもうあきらめた。 というかエラーメッセージすらとんちんかんな時があるのが頭痛い。 昔の仕事のプロジェクトコードのメンテでちょっとしたテンプレート書いてとかで 引っかかると泣きたくなる。
897 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 13:25:22 ] >>894-895 まるで、複数コンパイラで有効なテンプレートを書くのが上級者であるかのような言い方だな。 そういった汎用性のあるテンプレートは入門者レベルの機能しか使ってない。 君らは、入門者レベルのテンプレートしか書いたことないんだろ?
898 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 13:31:55 ] スレの存在を否定するような行為が、目下のベストな対処法 「技巧に走らない」
899 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 14:04:38 ] >>897 > であるかのような言い方だな。 印象だけでものを書く場合、その印象がトンチンカンだと 残りの文章がすべてトンチンカンになるから今後は気をつけな。
900 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 14:25:57 ] シンプル伊豆ベスト
901 名前:デフォルトの名無しさん mailto:sage [2005/09/10(土) 15:15:35 ] >>897 「入門者レベル」とか「汎用性のある」とか、 自分が「上級者」じゃない事がバレバレなんですがw まぁ、恥の上塗りだけはしないようになw
902 名前:名無しさん@そうだ選挙に行こう [2005/09/10(土) 18:43:40 ] >>888 つまり、templateに限らずC++は糞だって事で包茎?
903 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/10(土) 19:37:56 ] ていうかお前が包茎。
904 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/10(土) 19:45:33 ] 24時間テレビ C++ は地球を救う
905 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/10(土) 20:09:37 ] >>902 ,904 んなこたーない。
906 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/10(土) 22:11:14 ] >>894 は馬鹿だな。
907 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 01:31:57 ] 894は、VC以外でも通るように、typenameちゃんと書けとか その程度の意味じゃねえの?
908 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 05:40:17 ] 言語仕様が複雑すぎて処理系が追いつかないのは本末転倒 言語仕様満たしてから最適化とかやれよ馬鹿ベンダーはよ 現実逃避してんじゃねーよ
909 名前:名無しさん@そうだ選挙に行こう [2005/09/11(日) 07:05:25 ] ヒント:需要と供給
910 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 09:16:30 ] つまりDelphiが最強ということになるな。
911 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 09:37:08 ] Delphi知らないんだけどtemplateみたいなのあるの?
912 名前:名無しさん@そうだ選挙に行こう mailto:sagen [2005/09/11(日) 09:44:31 ] あるか!
913 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 09:52:58 ] なぜ怒る・・・。 そこがDelphi信者のコンプレックスなのか?
914 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 09:57:55 ] でもDelphiってすごいよね 一代でここまでメジャーになった言語パッケージってないでしょ それともPascalの下積みがあったから?
915 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 10:18:13 ] >>914 世間ではC#の方がメジャーだと思うがね。
916 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 10:20:04 ] C#は単なるM$の宣伝力だと思うけど
917 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 11:13:26 ] >>916 CとかC++から名前の連続性もあるしね。
918 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 12:07:50 ] C#なんて使って製品開発とかしてる香具師っているの?
919 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 14:40:54 ] 天下のM$がVBで真似したぐらいだからな 当時はRADは斬新な開発環境だった
920 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 15:18:44 ] Delphi使いこそプログラマの頂点ということか。
921 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 16:34:19 ] Delphiが当初からMS謹製であったならば、VBだ、MFCだ、ATLだ、WTLだ、 STLだ、.Netだ、C#だ、C++/CLIだといったことで右往左往することもなく 10年間一貫とした言語体制、RAD環境、爆速コンパイル、コンポーネント化 による高い生産性等々を皆が維持・共有できたかと思うと残念でならないよ。
922 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 16:49:55 ] C#って、Delphi作った香具師が理想の言語として設計したんだろ。 Delphi信者御苦労様w
923 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 18:34:04 ] まだDel厨いたのか そろそろ博物館に行けよ
924 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 20:14:45 ] 博物館の恐竜が一緒に浮かれて踊ったぜ
925 名前:名無しさん@そうだ選挙に行こう mailto:sage [2005/09/11(日) 23:35:20 ] >>921 STLだけその中で異質だな。
926 名前:デフォルトの名無しさん mailto:sage [2005/09/12(月) 09:47:06 ] 予想通り嫌Del厨が暴れることになったか・・・
927 名前:デフォルトの名無しさん mailto:sage [2005/09/12(月) 11:54:51 ] つか、スレ違いうぜぇですよ?
928 名前:デフォルトの名無しさん mailto:sage [2005/09/12(月) 11:58:56 ] >>924 子門乙
929 名前:デフォルトの名無しさん [2005/09/14(水) 15:45:52 ] template< typename char_type, tepename char_traits > std::basic_ostream< char_type, char_traits >& operator<< ( std::basic_ostream< char_type, char_traits >& stream, const int& value ) { stream << "value = " << value << endl; return stream; } この関数内で文字列リテラル"value = "を char_type がcharなら、"value = " char_type がwcharなら、L"value = " にしたいんですが、どうしたら良いでしょうか?
930 名前:デフォルトの名無しさん mailto:sage [2005/09/14(水) 16:12:57 ] >>929 テンプレートの特殊化か、オーバーライドで解決させる。 ex) inline char const * choice( char const * s, wchar_t const *, char ) { return s; } inline wchar_t const * choice( char const *, wchar_t const * s, wchar_t ) { return s; } stream << choice("value=",L"value=",char_type()) << value << endl;
931 名前:929 mailto:sage [2005/09/14(水) 16:31:48 ] >>930 #define literal_str( char_type, str ) choice( str, L##str, char_type##() ) 付きで採用しますた。 ありがとうございました。
932 名前:デフォルトの名無しさん mailto:sage [2005/09/14(水) 17:21:04 ] >>931 二番目の##は余計。
933 名前:929 mailto:sage [2005/09/14(水) 21:31:05 ] だからなんだよこのタコ助!
934 名前:デフォルトの名無しさん mailto:sage [2005/09/14(水) 22:41:20 ] 確かに余計だな。
935 名前:929 mailto:sage [2005/09/15(木) 00:04:09 ] >>933 >>929 の著作権は私にあります。 なんなら出るとこ出ても・・ と思いましたがきっと>>933 は 私にインスパイヤされて誕生した新種なんでしょう。 今回はかんべんしてやります。
936 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 11:53:02 ] template <class T> void f1(T t) { f2(t); } void f2(int) {} int main() { f1(1); } というコードは正しいのでしょうか? VC7.1 ではコンパイル可能で comeau ではコンパイルできません。
937 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 12:50:56 ] >>936 comeauだとなんてエラーが出るの?
938 名前:636 mailto:sage [2005/09/15(木) 13:09:16 ] >>637 identifier "f2" is undefined detected during instantiation of "void f1(T) [with T=int]" というエラーです。strict mode のみのようです。 ちなみに、ユーザ定義型の場合は期待通りにコンパイルできました。 template <class T> void f1(T t) { f2(t); } struct a{}; void f2(a) {} namespace adl { struct a{}; void f2(a) {} } int main() { f1(a()); f1(adl::a()); } このコードはコンパイル成功。
939 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 14:23:18 ] >>936 gcc3.4.4(MinGW) で、-Wallで通る。
940 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 14:26:00 ] >>938 プロトタイプ宣言したら?
941 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 14:31:54 ] >>938 f2()のプロトタイプ宣言が必要っぽい。
942 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 16:28:36 ] Incompatibilities Between ISO C and ISO C++, David R. Tribble david.tribble.com/text/cdiffs.htm#C90-impl-func ・ Implicit function declarations > C++ does not allow implicit function declarations. It is invalid to call a function > that does not have a previous declaration in scope. > > C99 no longer allows functions to be implicitly declared. > The code above is invalid in both C99 and C++.
943 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 17:47:26 ] >>936 標準の (14.6.4.2/1) をそのまま読む限りでは, unqualified name lookup として 解決される名前は point of definition の文脈のみが考慮されて, associated namespaces を用いた名前解決(要するにADL)では,point of definitionと point of instantiation の双方の文脈が考慮されるみたいですね.なので, >>936 の f1(1) という呼び出しにおける f1 中の f2(t) に対する名前解決の場合, unqualified name lookup では f2 の呼び出しを定義している場所(point of definition) からは f2 という名前は解決されないので失敗し,さらに f2(t) は int を引数とした 呼び出しのために associated sets of namespaces and classes も空 (3.4.2/2) の ため,ADL 経由でも f2 は見つからずに,結果 f2(t) という関数呼び出しに対応する 名前の解決が失敗する. 一方で,>>938 の f1(a()) 及び f1(adl::a()) という呼び出しにおける f1 中の f2(t) に対する名前解決の場合,>>936 と同様 unqualified name lookup による名前解決は 失敗する.ところが,a 及び adl::a はユーザ定義型で,各々グローバルと adl が associated namespace になる.この場合,f2(t) という呼び出しが定義されている 場所 (point of definition) と f1 がインスタンス化された場所 (point of instantiation) 双方の文脈が名前解決において考慮される.結果, point of instantiation の文脈で void f2(a) と void adl::f2(adl::a) が visible のため,これらの名前解決が成功する. と,こういう感じだと思います.ちなみに VC++7.1 の挙動は,dependent name だろうが non-dependent name だろうが,ADL 経由だろうがなかろうが,全て point of instantiation の文脈も考慮するという実装になっているための結果で, これは標準に準拠した挙動ではないです.
944 名前:943 mailto:sage [2005/09/15(木) 17:49:27 ] あ,すいません.長々と書きましたけれど結論としては, 936のコードは(標準に準拠していないという意味で)正しくないと思います.
945 名前:936 mailto:sage [2005/09/15(木) 22:07:49 ] >>943 なるほど。 実体化の時点で名前の解決を行っても、 実体化の時点の文脈が考慮されるとは限らないんですね。 皆様、ありがとうございました。
946 名前:デフォルトの名無しさん mailto:sage [2005/09/15(木) 22:41:25 ] template<class T> class Foo { public: ...; private: class Bar { public: ...; bool operator()(const Bar& l, const Bar&r) const; private: T m_value; int misc_info; }; std::multiset<Bar, Bar::Comp> m_bars; }; m_bars の先頭・末尾に番人(misc_value などは他のメ ンバと同様にアクセス可能にしたもの)を導入したいの ですが、どういうアプローチで作れば良いでしょうか?
947 名前:デフォルトの名無しさん mailto:sage [2005/09/16(金) 01:33:46 ] >>946 undeclared identifier `misc_value'
948 名前:デフォルトの名無しさん mailto:sage [2005/09/16(金) 09:43:59 ] >>946 テンプレート関係ないやん。
949 名前:デフォルトの名無しさん mailto:sage [2005/09/18(日) 16:56:08 ] STLportではコンパイルできるけれど、 g++のSTLではエラーが出てしまうようなコードってどんなものがあるでしょうか? vectorやstringくらいしか使ってないんですが、コンパイルでエラーが出ます。。
950 名前:デフォルトの名無しさん mailto:sage [2005/09/18(日) 17:25:59 ] エラーメッセージ書かん奴には答えない
951 名前:デフォルトの名無しさん mailto:sage [2005/09/18(日) 17:33:35 ] >>949 氏ね!
952 名前:デフォルトの名無しさん mailto:age [2005/10/05(水) 16:55:29 ] template<int num, int count> struct power{ enum { value = power<num, count-1>::value * num }; }; template<int num> struct power<num, 1>{ enum { value = num }; }; template<int num> struct power<num, 0>{ enum { value = 0 }; }; template<> struct power<0, 0>{ enum { value = 0 }; }; ∋oノハヽo∈ ( ´D`) <テンプレート ♪ で、計算♪計算♪ age♪ age♪ (つ┳9 (_)┃_) ━§━ § ⌒ヽ〃⌒ヽ〃 int main() { //2の8乗 cout << power<2, 8>::value << endl; return 0; }
953 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 18:45:40 ] >template<int num> struct power<num, 0>{ enum { value = 0 }; }; それはどうかと思うぞ。
954 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 19:02:12 ] template<int num> struct power<num, 0>{ enum { value = 1 };};
955 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 19:13:50 ] <0,0>,<num,1>の特殊化は必要ないな
956 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 21:12:57 ] むしろこうしてコンパイル時エラーにしろよ。 template<> struct power<0, 0>{};
957 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 21:24:22 ] 0^0って数学的にはどうなるの?
958 名前:ヽ(´ー`)ノ ◆.ogCuANUcE mailto:sage [2005/10/05(水) 22:22:38 ] >>956 n^0 = 1
959 名前:ヽ(´ー`)ノ ◆.ogCuANUcE mailto:sage [2005/10/05(水) 22:23:20 ] スマン。レス番間違えた orz
960 名前:デフォルトの名無しさん mailto:sage [2005/10/05(水) 22:28:09 ] >>957-958 一方で0 ^ n = 0となっているから問題になる。 ところで^と言えばXORの立場が。
961 名前:デフォルトの名無しさん mailto:sage [2005/10/06(木) 12:22:20 ] VC6のtemplate関数ってバグある気がするんだけど... template<typename T> void test(); 引数無し呼んだときに解決できてないみたい... template<typename T> void test(const T&); みたいにすればオーバーロードで解決できるのか、大丈夫みたいなんだが...
962 名前:デフォルトの名無しさん mailto:sage [2005/10/06(木) 12:36:11 ] いまどきそんな化石コンパイラに文句言われても…
963 名前:デフォルトの名無しさん mailto:sage [2005/10/06(木) 13:39:14 ] 化石以前にtemplateに関しては欠陥コンパイラですから・・・
964 名前:デフォルトの名無しさん mailto:sage [2005/10/06(木) 17:42:46 ] そもそもC++コンパイラじゃないですから
965 名前:デフォルトの名無しさん mailto:sage [2005/10/06(木) 22:25:31 ] 少なくともANSI/ISO C++準拠とは言えないな。
966 名前:デフォルトの名無しさん mailto:sage [2005/10/07(金) 04:44:36 ] じゃーVC7はどうですか?
967 名前:デフォルトの名無しさん mailto:sage [2005/10/07(金) 05:23:27 ] 7.1はかなりまとも。
968 名前:デフォルトの名無しさん mailto:sage [2005/10/07(金) 12:23:52 ] 7と7.1は全然違うぞ 7はかなり微妙
969 名前:デフォルトの名無しさん mailto:sage [2005/10/07(金) 13:11:10 ] 7はCStringにバグがあったね。STL周りもちょっと不安定なところがあった気もする。
970 名前:デフォルトの名無しさん mailto:sage [2005/10/07(金) 14:50:27 ] 7.1って具体的にclのどのバージョン? 今 Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 っての使ってるけど
971 名前:デフォルトの名無しさん mailto:sage [2005/10/07(金) 15:06:35 ] VS.net(VC.net)2003か、VCTK2003のやつが7.1 13.10.3077なら7.1だな。VS.net2003の方のやつだろ。
972 名前:デフォルトの名無しさん mailto:sage [2005/10/14(金) 17:36:27 ] codeguruに記事の投稿してみたがレビュー通んないとだめなんだね
973 名前:デフォルトの名無しさん [2005/10/18(火) 15:57:25 ] age
974 名前:デフォルトの名無しさん mailto:sage [2005/10/26(水) 22:29:10 ] 人稲杉なので、バカネタを投下。 www.hakusi.com/up/src/up5538.zip.html Boost.Lambda みたいに Expression Template を使った、引数に対して安全なフォーマットライブラリ。 Boost.Function や、Boost.Bind と組み合わせることが可能。 以前作成したものと違い、オマケ機能だが入力も可能で、ワイド文字にも対応。 ただ、 _ と % だらけで見た目がキモイ上に、実用性がイマイチ謎。 Expression Template の資料として。 // 出力 string strA, strB; sprint( strA, "1 " % !_x[6] % "/" % _s, 10, "aaaa" ); // sprintf( str, "%#6x/%s", 10, "aaaa" ); みたいな。 sprint( strB, "2 " % (!_x[6]*='0') % "/" %_s, 10, "aaaa" ); // sprintf( str, "%#06x", 10, "aaaa" ); みたいな。 cout << strA << endl; // 1 0xa/aaaa と出力 cout << strB << endl; // 2 0x000a/aaaa と出力 // 入力 int xA, xB; string yA, yB; sscan( strA, "1 " % _ws % _x % "/" % _s, xA, yA ); // 空白部分はスキップさせる sscan( strB, "2 " % _x % "/" % _s[3], xB, yB ); // 文字列部分は3文字のみ取得 // 出力 print( cout, "xA = " % _d % "\nyA = " % _s % _endl, xA, yA ); print( cout, "xB = " % _d % "\nyB = " % _s % _endl, xB, yB ); // xA = 10 // yA = aaaa // xB = 10 // yB = aaa と出力
975 名前:デフォルトの名無しさん mailto:sage [2005/10/27(木) 00:15:14 ] >>974 せっかくなので便乗しておきますね.将来の話なのでアレですけれど. www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1603.pdf
976 名前:デフォルトの名無しさん mailto:sage [2005/10/29(土) 10:05:49 ] 難読コンテスト会場はここですか?
977 名前:デフォルトの名無しさん [2005/10/31(月) 13:08:43 ] >>974 すげー--w 確かに scanf っぽいこと出来るし。 でも、Perl みたいで汚いな。使おうとは思わんけど。
978 名前:デフォルトの名無しさん mailto:sage [2005/10/31(月) 13:59:50 ] >>974 マジキモス
979 名前:デフォルトの名無しさん mailto:sage [2005/11/02(水) 14:02:41 ] >>974 良くこんなん書く気になるなあ。
980 名前:デフォルトの名無しさん mailto:sage [2005/11/02(水) 14:40:35 ] >>975 boostな人達はあれば便利だけど、一般人的にはどうなのかなあ?
981 名前:デフォルトの名無しさん mailto:sage [2005/11/02(水) 16:19:39 ] >>980 どの辺が便利なのか理解に苦しむ。
982 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 13:49:05 ] >>980 型安全な printf, scanf というのが一番インパクトが大きいと思います. 後,lambda のような(擬似的な)可変長テンプレート引数を使ったライブラリの コンパイル時メッセージが見やすくなるというのもあるかと. >>981 Boost な人にとっては,これまでプリプロセッサなどで力技で実装していた Function, Tuple, MPL, Lambda など多くのライブラリの実装が 非常に楽に見通しよく実装できるようになり,便利になると思います.
983 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 15:15:01 ] >>982 コンパイルエラーなどたいして問題じゃないけどね。 それよりもデバッグの方が大変。
984 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 15:19:33 ] 変な拡張するより単にプリプロセッサを名前空間対応にすればいいだけちがうの?
985 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 15:30:42 ] >>984 それじゃプリプロセッサにならないでしょ。
986 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 17:19:51 ] え、C/C++のプリプロセッサってトークン理解してるはずなんだけどなあ。 商用じゃプリプロセスと同時に解析するのが主流だし。 テンプレート引数程度の局所的変更じゃ根本的解決にならないでしょ。
987 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 17:26:54 ] 名前空間を通常のものとプリプロセッサで共有しようとすると 泥沼になる気がする。(例えば # define STD_BEGIN namespace std{ とか) pp専用の名前空間ならwaveが実験的に対応している。
988 名前:デフォルトの名無しさん mailto:sage [2005/11/03(木) 22:37:23 ] プリプロセッサと言えば、C++/CLIでとんちきな拡張してるよ。 スペース区切りキーワードってやつ。 www.microsoft.com/japan/msdn/vs05/visualc/TransGuide.asp
989 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 00:29:44 ] プリプロセッサと本体の間のフォーマットってANSIか何かで標準規格ある? #132 "hogehote.h" たいていはこんなの出るんだよね?
990 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 01:08:57 ] 次スレ立てて良いですか?
991 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 01:21:16 ] C++相談室で十分だと思うんだ。
992 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 01:32:58 ] ハゲドー 一年もかかってやっと1スレなペースだし
993 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 01:40:20 ] >>983 > コンパイルエラーなどたいして問題じゃないけどね。 断言君さようなら
994 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 11:26:29 ] 断言君だって。なにその俺様用語w オナニーマクロだらけの糞コード書いてる奴は 日本語にもそれが出るね。
995 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 12:12:24 ] 断言君 の検索結果 約 926,000 件中 1 - 10 件目 (0.27 秒)
996 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 12:25:58 ] 俺も>>983 を支持する。 ランタイムエラーが恐ろしいのであって、 コンパイルエラーなどコンパイラとの対話交渉に過ぎない。
997 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 13:14:27 ] てかさ、コンパイルエラーが出てたら、 そもそも実行ファイルはビルドされて無いんじゃないか? ワーニングなら分かるけど。
998 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 13:49:38 ] つぎスレ立てるかどうか迷っているんだが このスレのタイトルをよく吟味したら 「統合」:いくつかの物を一つにまとめあわせること このように辞書では出ている。 つーことは「STL相談室」も「BOOSTを語れ」も入らないよーな気がした。 それとも、ここのつぎスレが要らないのか? そんな疑問を抱いてしまって、俺には次スレを立てる勇気がない。 さあ。次をたてる勇者はだれか。
999 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 13:53:56 ] boostは微妙だがSTLスレもこのスレも必要なし あっても混乱するだけ
1000 名前:デフォルトの名無しさん mailto:sage [2005/11/04(金) 14:02:28 ] STLを使うと実行ファイルのサイズが10倍になるから スレは統合すべきだと思います。
1001 名前:1001 [Over 1000 Thread] このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。