- 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 あたりに。
- 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> { ... }; // 特殊化版
|

|