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 あたりに。
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 ] 実体化の位置を決定するルールは結構複雑だからな。