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 あたりに。
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なのは分かったけど