08/02/16 12:45:02
・ここはC++のテンプレートメタプログラミング専用スレです。
・なかったので立てました。
・前にもあったような気がするけど気にしない。
・次期C++(0x) boost STLの話題も、TMPに関係するならここにどうぞ。
仲良く使ってね。
2:デフォルトの名無しさん
08/02/16 12:48:44
とりあえずTMP始めてだから優しくしてね><って人には
p_stabeのとこのブログのログを最初から読んだりしてみる事から始めるといい。
3:デフォルトの名無しさん
08/02/16 12:49:15
すいません、やっぱり、該当スレでお願いします。
申し訳ありませんでした。
4:デフォルトの名無しさん
08/02/16 12:49:55
おい>>1、メタだけあってもしょうがないだろ
何を話題にすりゃいいんだ
5:デフォルトの名無しさん
08/02/16 12:50:02
>>1 乙
6:デフォルトの名無しさん
08/02/16 12:50:48
>>4
いくらでも話題はあるさね
7:デフォルトの名無しさん
08/02/16 12:51:13
>>4
template<fugafuga>を使った機能とか、
必要であればプリプロセッサも絡めてもらうとありがたいです。
8:デフォルトの名無しさん
08/02/16 12:53:14
>>7
だったらテンプレートスレにしておけば良かったのでは・・・
なぜメタ限定?
9:デフォルトの名無しさん
08/02/16 12:55:49
>>8
テンプレートスレならNTPとかMOJOばっかりで
Lispみたいなメタプログラミングは話題にし辛いだろう。
ここはそういうのを扱うスレ。コンパイル時点での、コードに対するプログラミングに関するスレ。
10:デフォルトの名無しさん
08/02/16 12:59:04
>>8
激しく同意だな
でも、テンプレートスレじゃboost、STL、C++スレでカバーで良いんじゃね
11:デフォルトの名無しさん
08/02/16 13:01:05
とりあえずPreprocessor Metaprogramming万歳
12:デフォルトの名無しさん
08/02/16 13:02:02
メタプロと普通のテンプレート使ったプログラムは全然違うだろう。
13:デフォルトの名無しさん
08/02/16 13:02:20
STLスレやboostスレとか何度も統廃合の話題が出てその度に荒れていたな
14:デフォルトの名無しさん
08/02/16 13:02:53
スレが立った初っ端からいろいろ文句つけてる奴は何だ?
現在、板の各所に散らばっている“テンプレートスレ”で満足しているならこんな所覗く必要はないだろう。
“メタプログラミング”を話題にしたい奴がここを必要としているんだ。興味がないなら来るな。
15:デフォルトの名無しさん
08/02/16 13:03:31
そうだそうだ
16:デフォルトの名無しさん
08/02/16 13:04:05
いや、興味あるとかないとかそういう問題じゃねぇーだろw
17:デフォルトの名無しさん
08/02/16 13:04:26
別にMetaProgrammingであればTemplateは必要なかったのでは?
誤解を招くだけだし。
あと、
>>1
>仲良く使ってね。
18:デフォルトの名無しさん
08/02/16 13:05:07
メタプロが理解できない奴が嫉妬してクレーム付けてるだけだろ
19:デフォルトの名無しさん
08/02/16 13:06:21
勢いが1234もある。
過疎ったVIPスレ並みに速い流れだな。その割には糞なレス多いけど。
20:デフォルトの名無しさん
08/02/16 13:07:05
{
std::ofstream f( "tmp.cpp" ) ;
f << いろいろいろいろいろいろ ;
}
system( "cc tmp.cpp" );
system( "a.out" );
では、このあたりからw
21:デフォルトの名無しさん
08/02/16 13:08:30
クラックしがいがありそうだなw
22:デフォルトの名無しさん
08/02/16 13:10:44
>>20
テンプレート(ライブラリ)を使ったメタプログラミングだwww
23:デフォルトの名無しさん
08/02/16 13:15:15
だいたい、>>1がアホだからいけないんだ
Templateなんて入れるないで、素直にC++/メタプログラミングすればよかった
24:デフォルトの名無しさん
08/02/16 13:17:33
>8
Boost, STLとの統合の話題が出てくるからじゃね?
あっちは使い方、こっちは実装テクニックと使い分けできるといいね。
そういやポリシーってみんなどんぐらい使ってる?
template<class T> class M : public T {};
struct T1 { void t1() {}; };
struct T2 { void t2() {}; };
M<T1>().t1();
M<T2>().t2();
とか、インターフェースの差し替えが出来てけっこう便利な気がするんだけど。
25:デフォルトの名無しさん
08/02/16 13:19:13
単純にテンプレートテクニックスレで良かったんじゃね、とか
26:デフォルトの名無しさん
08/02/16 13:20:59
とりあえず同名の本の解答集
URLリンク(www.crystalclearsoftware.com)
例えば演習2-3で型を文字列で出力するテンプレートを作りなさいなんて問題あるけど、
std::cout << type_descriptor<long const*&>();
これ、C++だと volatile, const, ポインタ、参照でそれぞれ specialization で場合分け
し、さらに基本型の int, long, char, double とかでさらに場合分け
とかなって、なんだか力業だなぁとか感じる(答参照)。
27:デフォルトの名無しさん
08/02/16 13:22:12
>>24
スーパークラスに直接Tをいれるのはコンパイルが異様に重くなるので最近は避けているな。
28:24
08/02/16 13:27:07
>27
エエエ(ry
コンパイルなんて昔に比べると激早だから、あんまり気にしないなあ。
どちらかというと使う側でpimplとかの工夫してるし。
29:デフォルトの名無しさん
08/02/16 13:28:41
そおか、C++以外の言語を使ったあとだと余りの遅さにかなりショックを受けるんだが。
30:デフォルトの名無しさん
08/02/16 13:34:03
100ファイル程度あると、C++は自作オーバークロックの最強マシンをもってして三十分や一時間かかりかねないけれど
これがC#だとヘナチョコマシンでも一分掛かるか掛からないかといった所。
31:デフォルトの名無しさん
08/02/16 13:37:46
コンパイル時間のほとんどは
プリプロセスなんだろうなあ。
32:デフォルトの名無しさん
08/02/16 13:48:27
>>30
どう考えてもそれは長すぎる
せいぜいかかっても1ファイルに2~3秒ってところじゃないの?
33:デフォルトの名無しさん
08/02/16 13:48:37
Boost.Lambdaのヘッダをプリコンパイルドヘッダに入れようとすると、
pchがぶくぶく膨らんでいく。
後のコンパイルでは、プリコンパイルドヘッダの読込も
ボトルネックになっているのではという気がしてならない。
34:デフォルトの名無しさん
08/02/16 13:50:18
>>31
よほど凝ったことしなきゃそれはないだろ
35:デフォルトの名無しさん
08/02/16 13:51:20
プリコンパイルでどれだけの時間が短縮されるか考えたら
そんなもんだと思う
36:デフォルトの名無しさん
08/02/16 13:52:37
プリコンパイルは一応コンパイルもしてるわけで
37:デフォルトの名無しさん
08/02/16 13:55:07
>33
ヘッダを重くするとそうなるけど、それこそpimplで隠したら?
Boost.Lambdaをヘッダに突っ込もうとする時点で何か設計で失敗している気がするけど。
#ライブラリを設計しているのならしょうがないけど
38:デフォルトの名無しさん
08/02/16 13:59:49
$ cat test.cpp
# include <boost/lambda/lambda.hpp>
int main()
{
using namespace boost::lambda;
int i = 4;
return (_1 + _1 + 1)(i);
}
$ time g++ test.cpp
real 0m1.175s
user 0m0.900s
sys 0m0.068s
$ time cpp test.cpp >/dev/null
real 0m0.249s
user 0m0.160s
sys 0m0.024s
39:デフォルトの名無しさん
08/02/16 14:03:25
>>37
たしかにLambda自体は特定のcppファイルでしか使っていない。
こういうときはプリコンパイルドヘッダから外すべきなのか?
40:デフォルトの名無しさん
08/02/16 14:05:43
そらそうだな。
41:デフォルトの名無しさん
08/02/16 14:09:20
>39
ヘッダは基本的にインターフェイスなんだから、インターフェイスに不要な実装は隠すのが望ましい。
テンプレート使ってるとそんなことも言ってらんないけど。
42:デフォルトの名無しさん
08/02/16 14:16:12
そろそろC++という言語自体を見直すのが望ましいという気もしないでもない
問題累積しすぎだろ
43:デフォルトの名無しさん
08/02/16 14:19:31
>>41
stdafx.hで何もかもインクルードしていたよ。
44:デフォルトの名無しさん
08/02/16 14:32:12
以前のスレを探してきた。
【C++】template 統合スレ -- Part6
スレリンク(tech板)
45:デフォルトの名無しさん
08/02/16 14:49:06
ある程度確定したクラス他は専用libに放り込んでるので無問題
46:デフォルトの名無しさん
08/02/16 14:58:08
・クラス単体のみの宣言だけ
class A;
・クラスのインターフェイスを含めた宣言だけ
class A{ void f(); };
2種類のヘッダを用意すれば(ry
47:デフォルトの名無しさん
08/02/16 16:28:15
>41
C++狂Herb Sutterの本を読んだほうが良いと思う。
ヘッダファイル: インターフェイスに関係するファイルを最低限
ソースファイル: できるだけこっちでインクルードする
が基本だよ。
48:デフォルトの名無しさん
08/02/16 16:31:58
コンパイル時間の節約は分かるんだが、
いざヘッダファイルをインクルードして何か使おうとすると
実装が無いとか文句言われることがあるのが困るんだよな。
49:デフォルトの名無しさん
08/02/16 16:32:21
実装じゃねえや。定義だ。
50:デフォルトの名無しさん
08/02/16 16:33:06
>>48
ただの誤用にしか聞こえんのだが、どういう状況の話?
51:デフォルトの名無しさん
08/02/16 16:39:01
不完全型のみで十分な状況では
その型を定義してあるヘッダをインクルードせず、
不完全型の宣言のみを書く。
そして、その型を使ってるソースファイルでのみ、
そのヘッダファイルをインクルードする。
52:デフォルトの名無しさん
08/02/16 16:59:36
なんかC++の基本もまともに出来ないような人が居ますね。
53:デフォルトの名無しさん
08/02/17 02:18:38
TMPやるにはHaskell勉強した方が良いって本当ですか?
54:デフォルトの名無しさん
08/02/17 02:20:47
>>53
変数への代入ができないという制約の下でどうやって問題を解決するかを学ぶ、
という点で本当だと思う。
55:デフォルトの名無しさん
08/02/17 10:28:54
SICP読んだらModern C++ Designが分かった
56:デフォルトの名無しさん
08/02/18 13:01:03
Scheme勉強したらModern C++ Designが分かった
57:デフォルトの名無しさん
08/02/18 13:47:54
あれって別の関数型言語を勉強してからじゃないと理解できないほど難しいか?
58:デフォルトの名無しさん
08/02/18 13:59:44
ムチャクチャな書き方をしないといけないからわかりにくいんだよ。
すっきりした表記の関数型言語を勉強した後だと
どういうトリックなのかがすんなり理解できる。
59:デフォルトの名無しさん
08/02/18 14:01:52
別に無茶苦茶ではないと思うが。
60:デフォルトの名無しさん
08/02/18 14:54:27
再帰に継承が絡んでくると難しく感じる。
61:デフォルトの名無しさん
08/02/18 14:56:58
慣れてないだけだな。それにあんなもの別にC++以外のものを触ったって慣れやしない。
62:デフォルトの名無しさん
08/02/18 15:32:39
ところで>>2のp_stabeには誰もつっこまないの?
p_stadeじゃないかって
63:デフォルトの名無しさん
08/02/18 15:37:29
q_stabe
64:デフォルトの名無しさん
08/02/18 16:57:57
>>61
それは違うと思う。関数型言語のほうが記法が簡便だが抽象度が高く
センスが必要。LispでもSchemeでも自在に扱えればC++のメタなんて少し
の時間でマスターできる。templateなんて少しの時間でマスターできる。
経験上確信してる。逆は成立しない。
65:デフォルトの名無しさん
08/02/18 17:19:20
千差万別、十人十色
自論に固執すること愚か也
66:デフォルトの名無しさん
08/02/18 17:32:39
言語に組み込まれてるってのは重要だよな。
C++だとマクロとかでちょっと文法の解釈を脳内変換すれば
いいんだけど手間が増大するのと
初学者に扱える代物ではなくなってしまうんだよね。
67:デフォルトの名無しさん
08/02/18 18:10:14
>>65
関数型言語の経験ないだろ?
68:デフォルトの名無しさん
08/02/18 18:10:49
>>65
SICPは読んだ?
69:デフォルトの名無しさん
08/02/18 18:25:10
負けへん、負けへん
山ちゃんは負けへんでええ
70:デフォルトの名無しさん
08/02/18 18:25:39
誰か質問しろよ。
スレ落ちるの時間の問題だな。
71:デフォルトの名無しさん
08/02/18 18:30:41
C++0xではmplは入らなくてTypeTraitsどまりってことは
mplはまだ重視されてないってこと?メイヤーズの本では
TMPがC++の中心に来ることはないなんて書いてあったけど
どうなんだろ?
72:デフォルトの名無しさん
08/02/18 19:20:00
そうなんでしょう。
だって頭の体操にはなるけど、あんまり実用性ないじゃん。
73:デフォルトの名無しさん
08/02/18 19:27:11
type_traitsはフレームワークであって、
みんなが自分のクラスのtraitsを提供しないと真価を発揮しないけど、
mplは使いたい人が使えばいいだけだから標準化しなくても困らない。
74:デフォルトの名無しさん
08/02/18 19:38:50
C++0x において提案されている <type_traits> で提供される機能の中には
コンパイラが持っている独自の情報を吐いてくれないと実装できないものも多いので
そういう意味で TypeTraits は優先的に規格として明示してくれないと困るかと
75:デフォルトの名無しさん
08/02/18 19:40:35
call_traits は追加されるの?
76:デフォルトの名無しさん
08/02/18 20:41:26
MP専用の構文を入れる気はもうないのかね
Templateでできたのはたまたまであって、
いつまでもあんなハックみたいな書き方したくないなぁ
77:デフォルトの名無しさん
08/02/18 23:08:07
バッドノウハウ
78:デフォルトの名無しさん
08/02/19 02:44:27
完全体のC++かどうかを判断するために
compiler_traits
が必要な気がする。
79:デフォルトの名無しさん
08/02/19 02:49:56
そうなるとまず has_compiler_traits が必要だな。
80:デフォルトの名無しさん
08/02/19 21:01:07
>>76
D言語の出番ですね、分かります
81:デフォルトの名無しさん
08/02/19 23:57:02
いやあ、すべってるねえ このスレ
82:デフォルトの名無しさん
08/02/20 00:07:56
昔ProgramingJemsにメタプログラミングでsinテーブルを生成するっていうネタがあった
当時メタプログラミングなんて知らなくて、
「すげぇぇぇぇ」と感動して自分でも作ってみた
しかし当時のオレのショボマシンではコンパイル時のサインテーブルの生成に結構な時間がかかり
最終的に、
Perlでテーブル書いたソースジェネレートした方が早くね?
という結論に
83:デフォルトの名無しさん
08/02/20 00:13:14
メタプログラミングとは?
テンプレート、型、typedef、コンパイル時定数、再帰を
駆使したコンパイル時プログラミングで合ってる?
84:デフォルトの名無しさん
08/02/20 00:15:48
テンプレートメタプログラミングならそれでまあ合ってる。
85:デフォルトの名無しさん
08/02/20 00:18:10
>>83
それはテンプレートメタプログラミングの説明だな
メタプログラミング自体はもっと広く、プログラムを操作するプログラム全般をいう
プリプロセッサを使うのもメタプログラミングだし、コードジェネレータを書くのも含む
86:デフォルトの名無しさん
08/02/20 00:20:22
テンプレート抜けてた。
87:デフォルトの名無しさん
08/02/20 00:43:39
そういう意味では82のPerlでソース生成と言うのも立派なメタプログラミング。
88:デフォルトの名無しさん
08/02/20 01:04:07
>>82
そんなあなたに constexpr@C++0x
89:デフォルトの名無しさん
08/02/20 01:06:00
一方D言語はsinを定数として畳み込んだ。
90:デフォルトの名無しさん
08/02/20 01:09:59
静的に実行できる関数は静的に実行してしまう。
D は中々のものだ。
91:デフォルトの名無しさん
08/02/20 01:35:24
D言語って誰が生みの親なの?
92:デフォルトの名無しさん
08/02/20 01:36:25
昔borlandで働いてた人
93:デフォルトの名無しさん
08/02/20 01:37:28
をるたん
94:デフォルトの名無しさん
08/02/20 01:40:52
>>92
じゃあ流行らないな
95:デフォルトの名無しさん
08/02/20 01:43:40
ボーランドはちがくね?
96:デフォルトの名無しさん
08/02/20 18:26:21
>>82
まあC++のテンプレートはメタプログラミングのために設計されてないからねえ。
マクロらしいマクロを持った言語なら、かなり高度なメタプログラミングをやってても
普通のコードの2倍やそこらの時間でコンパイルできる。
Lispの世界じゃ40年前からメタプログラミングが当たり前だし、
DOSの世界ではMASMのマクロで構造化なんてのが流行った。
97:デフォルトの名無しさん
08/02/20 18:35:23
ライブラリ作るときは主流になりそうだけどな。
てか、もうなってるか。
でもschemeのほうが言語機能としてcons listとか
があるから、より簡潔でストレス感じない。
C++のTMPはいかんせん表現がキモ過ぎる。
98:デフォルトの名無しさん
08/02/20 21:15:57
そこで constexpr ですよ
99:デフォルトの名無しさん
08/02/22 02:22:19
こんなの作ってみた。
自分のプログラムでは活用できてるからいいんだけど、意外と汎用性ないな……
struct UniqueNumber {
template<class type_t>
static unsigned int number() { static unsigned int n(count()); return n; };
private:
static unsigned int count() { static unsigned int c(0); return c++; };
}
100:デフォルトの名無しさん
08/02/23 01:51:48
>>83
プログラムを作るプログラムをプログラムしてみようって事だよ
当然、(プログラムをつくるプログラム)をつくるプログラムもね。
どこまででも逝ってくれ
101:デフォルトの名無しさん
08/02/25 16:49:57
>>99
typeidの速度が気になる場面で使うのかな?
102:デフォルトの名無しさん
08/02/25 17:07:03
>>99
struct UniqueNumber {
static unsigned int number() { return count(); }
private:
static unsigned int count() { static unsigned int c; return c++; }
}
これでよくない?
103:デフォルトの名無しさん
08/02/25 17:09:25
>>102
全然よくない。
104:デフォルトの名無しさん
08/02/25 17:13:44
>>103
何で?
type_tテンプレートパラメータ使われてないよ。
105:デフォルトの名無しさん
08/02/25 17:16:00
>>104
UniqueNumber::number<A>()とかUniqueNumber::number<B>()みたいな使い方するんでしょ。
で、テンプレートに渡した型毎に一定のユニークな値が返ってくると。
106:デフォルトの名無しさん
08/02/25 17:33:05
ああそうか
でも
cout << UniqueNumber::number<int>() << endl;
cout << UniqueNumber::number<int>() << endl;
cout << UniqueNumber::number<int>() << endl;
cout << UniqueNumber::number<char>() << endl;
cout << UniqueNumber::number<char>() << endl;
cout << UniqueNumber::number<float>() << endl;
やったら
0 0 0 1 1 2
となった。
何で、0 1 2 0 1 0にならないのかな?
107:106
08/02/25 17:38:05
わかりますた。なるほど。
108:99
08/03/01 03:50:23
応用例作ってみた。
URLリンク(fiercewinds.net)
継承で登録を強制できれば便利そうなんだけどなぁ。
あとファクトリ関数みたいに関数の引数とか戻り値にそのクラスを含む場合は、こんな大掛りな仕掛けは不要みたい。
……それ以前に言語側で何とかして欲しいよな。こんなの。
109:デフォルトの名無しさん
08/03/15 21:46:47
ちょっと質問です。
外部リンケージについて詳しく書いてある解説ってある?
具体的には関数内クラスをテンプレートパラメーターにして渡したいんだけどね。
externでも上手く行かんし……
110:デフォルトの名無しさん
08/03/15 21:51:35
それはそもそも無理じゃまいか?
111:106
08/03/15 22:19:26
>>109
規格上不可能
112:デフォルトの名無しさん
08/04/10 23:41:05
メタプログラミングしてると脳汁でます
113:デフォルトの名無しさん
08/04/11 00:39:33
なぜjavaやC#でtemplateが外されたか
不要物だからw
114:デフォルトの名無しさん
08/04/11 00:58:20
なぜJavaやC#でgeneri(ry
115:デフォルトの名無しさん
08/04/11 01:01:28
失ってから大切さに気付くものです
116:デフォルトの名無しさん
08/05/07 22:32:52
boost::mplとか使ってるコードで見る、
_1, _2ってどうやって実現してるんですか?
117:デフォルトの名無しさん
08/05/07 22:35:39
ソース読めばいいだろw
118:デフォルトの名無しさん
08/05/07 23:07:19
defineかtypedefだったかな
119:デフォルトの名無しさん
08/05/09 15:11:22
テンプレートで配列指定された場合エラーにする方法ってあるんでしょうか?
120:デフォルトの名無しさん
08/05/09 18:55:50
type_traitsのis_arrayとBOOST_STATIC_ASSERTを組み合せればいけるはず
121:
08/05/14 07:27:15
g++とVC2008どっちがテンプレート学ぶにはいいですか?
どっちがより完璧にテンプレートをコンパイルできますか?
122:デフォルトの名無しさん
08/05/14 07:35:58
どうみてもg++
123:
08/05/14 09:16:34
>>122
ありがとう。
124:デフォルトの名無しさん
08/05/19 02:14:25
テンプレートの実体化でテンプレート引数を特殊化にマッチさせる過程って
Prologの統一化と似てる気がする
125:デフォルトの名無しさん
08/06/01 02:40:06
>>99
のような型にユニークな数字を割り当てるのをコンパイル時にできないでしょうか?
boost::fusion::vectorに格納されている型をすべてユニークな型にしたいとき、
単純に片っ端から同じ型が含まれていないか調べると計算量がO(n*n)(nは格納されている型の数)になるかと思います。
そこで、boost::fusion::vectorをboost::mpl::sortしてboost::mpl::uniqueすれば
sortが平均O(n*log(n)), uniqueがO(n)だとすると先に説明した単純な方法より高速に計算する事ができるかと思います。
ですが一般的な型に対して順序関係はないのでboost::mpl::sortを実行することができません。
そこで>>99のような型毎に静的にユニークな数字を割り当ててboost::mpl::sortを適応させることができるようにしたいです。
長くなりましたが、皆様宜しくお願いします。
126:デフォルトの名無しさん
08/06/01 04:09:25
ムリじゃない?
分割コンパイルみたいな局面を考えると、ある型にユニークな数字が割り当て済かどうかすら判らんと思う。
リンカと連携すればいいんだろうけど、C++の規格はそこまで考えてないんじゃない?
指定された型のstaticポインタを用意してそのアドレスを使えばなんとかなるかも知れんが、どうなんだろ?
void*にキャストすれば比較もできるんじゃね?
127:デフォルトの名無しさん
08/06/01 18:57:02
そもそも数字の割り当て方を制御できないとソートする意味がなくね?
どう割り当てたいの?
128:デフォルトの名無しさん
08/06/01 19:09:24
どんな数値でもいいから割り当ててしまえば二分探索の恩恵を受けられるってことだろ
129:デフォルトの名無しさん
08/06/02 02:49:12
>>126
やはり無理なんですかね。
アドレスを得られるのはコンパイルのテンプレートの展開等の後の段階になるので無理だと思うのですが。
>>127
>>125で書いてある通り,型の集合の中に同じ型が含まれないようにすることが目的なので
boost::mpl::uniqueする前に同じ型が連続して並ぶようにboost::mpl::sortの結果が返ればよいのです。
ですので割り当てたい数字は型毎にユニークであれば何でもよいのです。アドレスもOK養豚場です。
>>128
二分探索を使って同じ型を消す処理をしてもO(n*log(n))で計算できそうですね。
そういう方法は考えていませんでした。
130:デフォルトの名無しさん
08/06/02 03:18:17
>>125
で書いた事をもう少しわかりやすく説明すると
例えば以下のような型があったとき、
typedef boost::fusion::vector<char, int, char, int> vec;
vecから重複する型を削除してユニークな型を保持するようにしたいのです。
typedef hoge<vec>::type unique_vec; //こんなhogeを欲しているのです.
BOOST_MPL_ASSERT(( boost::is_same<unique_vec, boost::fusion::vector<char, int> > ))
それで、以下の仮想コードのような方法を使とO(n*n)の計算時間が掛ります.
for i∈vec
for j∈vec
もしiとjが同じ型だったらjをvecからはずす.
そこで
typedef
boost::mpl::unique<
boost::mpl::sort<
vec, piyo>::type,
is_same<_1, _2> >::type
unique_vec;
とやればO(n*log(n))の計算量で済みます。
そこで上記のpiyoに相当するMetafunction class、
すなわち型に順序関係を与える方法を教えて貰いたいのです。
>>128
referenceにはboost::mpl::findは線形時間が掛ると書いてあるので
二分探索するには自分でコードを書かないといけないようです.
131:ヽ・´∀`・,,)っ━━━━━━━┓
08/07/09 14:39:37
>>124
静的(コンパイル時完全評価)だけどな。
VIPのスレで昔テンプレートでアッカーマン関数の問題解こうとしてドツボにハマった奴がいた。
132:デフォルトの名無しさん
08/07/16 20:46:07
『Modern C++ Design―ジェネリック・プログラミングおよびデザイン・
パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series) 』
ってのを読んでいる素人だけど、69ページのMostDerivedってのが
マジ分からん。今日、朝、昼、晩を合計で4時間ぐらい考えたんだが
どういう流れでこれで継承関係でいちばんの派生なのを特定できるのか
分からん。誰か分かる人いませんか?
133:デフォルトの名無しさん
08/07/16 21:05:22
結局、
typedef typename MostDerived<Tail, T>::Result Candidate;
では、再帰的に展開が繰り返され、MostDerived<NullType, T>に
なり、CandidateはTにしかなりえない
続く、
typedef typename Select<
SUPERSUBCLASS(Candidate, Head),
Head,
Candidate
>::Result ResultではCandidateはTと読み替えられるわけで
TがHeadのスーパークラスなら結果はHead
HeadがTのスーパークラスなら結果はTとなる
これじゃ全然ダメじゃね?
ググってみたけど、MostDerivedはダメだったって話を他でも見かけたよ
134:デフォルトの名無しさん
08/07/26 05:07:27
>133
>typedef typename MostDerived<Tail, T>::Result Candidate;
>では、再帰的に展開が繰り返され、MostDerived<NullType, T>に
>なり、CandidateはTにしかなりえない
どの段階で T にしかなりえないと思ってるのか分からないけどちゃんと再帰的に展開できてる?
MostDerived<TypeList<T0, TypeList<T1, NullType> >, T>::Candidate
# Head=T0, Tail=TypeList<T1, NullType>
→MostDerived<TypeList<T1, NullType>, T>::Result
# Head=T1, Tail=NullType
→Select<SUPERSUBCLASS(MostDerived<NullType, T>::Result, T1), T1, MostDerived<NullType, T>::Result>::Result
# MostDerived<NullType, T>::Result → T
→Select<SUPERSUBCLASS(T, T1), T1, T>::Result
結果として、
MostDerived<TypeList<T0, TypeList<T1, NullType> >, T>::Result
→Select<SUPERSUBCLASS(Select<SUPERSUBCLASS(T, T1), T1, T>::Result, T0), T0, Select<SUPERSUBCLASS(T, T1), T1, T>::Result>::Result
T と T1 を比較した結果、と T0 を比較した結果が返ってくる。
135:デフォルトの名無しさん
08/08/30 14:17:24
URLリンク(www.fides.dti.ne.jp) に
ローカルクラスの静的関数は関数テンプレートの引数に指定可能というのがあるのですが、
ローカルクラスのクラス内クラスの場合どうなりますか?
役立たずVC8だとノーチェックでOKにしたので確認できませんでした。
void func() {
struct local {
void operator()(int x) { cout << x << endl; }
static void f( int x ) { cout << x << endl; }
struct func {
void operator()(int x) { cout << x << endl; }
};
};
std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
for_each( v.begin(), v.end(), local::f );
for_each( vbegin(), v.end(), local::func() ); // これはどうなるの?
for_each( v.begin(), v.end(), local() ); //ホントはエラーのはず。VC8.0はOK……
}
136:デフォルトの名無しさん
08/08/30 15:00:49
VCだと言語拡張を有効にすることで関数内構造体もテンプレート引数に渡せてしまう。
俺はそれが嫌で言語拡張を無効にしてる。
137:デフォルトの名無しさん
08/08/30 16:07:38
>136
サンクス。無効にすると両方ともNGになりますね。
言語拡張を無効にすると色々なライブラリが使い物にならなくなるから、
さすがにそこまでストイックにはなれないなぁ……
138:デフォルトの名無しさん
08/08/31 17:08:18
言語拡張機能が使用された場合に警告を出すってオプションがあったと
思うんで、取り合えずそれONにしとけば?
139:デフォルトの名無しさん
08/08/31 17:37:41
そんなもの存在しません。
140:デフォルトの名無しさん
08/10/14 17:41:25
工エエェェ(´д`)ェェエエ工工
141:デフォルトの名無しさん
08/10/18 22:01:41
template <template <class Created> class CreatePolicy>
これのtemplate <class Create>部分の採用がヨクワカラナイ
どこかに良い説明のってないっすか
142:デフォルトの名無しさん
08/10/19 02:40:29
とりあえず検索用語だけ
template-template-parameters
143:デフォルトの名無しさん
08/10/24 23:27:12
class Hoge {
template <int X> void Fuga() {...}
};
テンプレート引数Xの値を、静的な値として集めることってできますか?
具体的には、呼び出されたFugaのうち、最も大きいXを取得して、別のクラステンプレートに渡すとか。
144:デフォルトの名無しさん
08/10/26 01:21:18
>>143
パッとみて無理っぽいうえにコンパイル単位をまたぐ場合を考えるとさらに無理っぽい。
145:デフォルトの名無しさん
08/10/30 20:35:00
(´;ω;`)
146:デフォルトの名無しさん
08/11/26 04:36:26
>>142
横だけど、meta templateでググっても見つからなく困っていたので助かった。
そういう用語だったのか…
147:99
09/01/12 20:40:07
まいど。
どうしても欲しくなったのでマルチメソッドを実装したんだけど、もっと効率的になる改善点てあります?
(詳細)URLリンク(cvs.sourceforge.jp)
(解説)URLリンク(fiercewinds.net)
解説がクソなのは置いといて下さい。
もっと良い実装があればそれも紹介して欲しいです。
個人的には
・いちいち登録しなきゃいけないのが面倒。
・トランポリン関数を保持する配列が疎になるのでメモリ効率が悪そう……
というところが気になるところです。
148:99
09/01/13 00:44:59
ちょっとだけ >147を修正。
登録をヘルパークラスに任せることにしました。少しはスマートに見えるけど、受け入れる型を
全部登録しなきゃいけないのは変わらず……
色々と考えてみたけど、どうやっても仮想関数に型情報は渡せなさそうね……。
149:99
09/01/13 01:15:20
リンク間違えてたので修正します。
(詳細)URLリンク(cvs.sourceforge.jp)
150:デフォルトの名無しさん
09/01/19 20:24:39
ポリシーによるプログラミングで質問です。
適当な乱数を発生させるTraitsクラスを何個か定義します。
struct r {int rdm(){return rand()%128;}};
struct rs{int rdm(){return rand()%7+60;}};
そんで、Traitsを使うクラスがこれ。ここまでは順調です。
template <class T=r> class R{int rdm(){return T.rdm();}};
この後、rdm関数が引数を持つようなTraitsを加えようとすると型があわないため困りました。
しかし、こういうケースは良くあるのではないかと思います。
struct rc{int rdm(int n){return n*(rand()%128);}
少し悩んでこんな解を出して見たのですが
こういう場合、みなさんどのように解決されますか?
template <int N> struct rt{int rdm(){return N*(rand()%128);}
R<rt<3> > r;
↑この場合、途中で引数を変えたいと思った場合毎回インスタンスを作る必要がある点が若干面倒です。
また、整数引数しか使えません
関数でやる場合は引数変更は楽ですが
Traitsにあたるものが増えてくると関数の組み合わせ爆発が大変です。
手法にこだわりはないのでこのやり方が楽、などあればきいてみたいです。
151:デフォルトの名無しさん
09/01/19 20:35:21
struct r{ int rdm(){ return rand() % 128; } };
struct rs{ int rdm(){ return rand() % 7 + 60 } };
template<typename Ty> struct rc{ Ty value; int rdm(){ return value * (rand() % 128); } };
後はrc::valueのゲッター書くなりセッター書くなりしろ。
152:150
09/01/19 21:33:25
>>151
ありがとう。参考にします。
153:デフォルトの名無しさん
09/01/19 23:44:40
STL コンテナでアロケータを指定する方法を真似するのは、何か都合が悪いの?
template <class T=r > struct R {
T t;
R( const T & t_ = T() ) : t(t_) {}
int rdm() { return t.rdm(); }
};
R< random_with_number > rn( random_with_number(3) );
154:デフォルトの名無しさん
09/01/24 14:16:13
>>153
これは良いですね!頂きます。
使ってみて、若干罠というか、引数なし版はプロトタイプ宣言と勘違いされるため
R<r> a(r()); //error
こうする必要があるんですね(もっと良いやり方があるのかは知らないですが・・)
R<r> b(*(new r()));
これを参考に、少し書き換えて見ました
struct b {virtual int rdm(){return 0;}};
struct r:b {int rdm(){return rand()%128;}};
struct rs:b{int rdm(){return rand()%7+60;}};
struct rc:b{
int val;
rc(int n) : val(n){}
int rdm(){int tmp=rand()%7;if(tmp%val==0){return tmp;}else{return rdm();}}};
template <class T=b > struct Q {
T* t;
Q( T* t_) : t(t_){}
int rdm() { return t->rdm();}
};
Q<> a(new rc(3));
Q<> b(new r());
155:デフォルトの名無しさん
09/01/24 14:55:23
>>154
> R<r> a(r()); //error
R<r> a((r()));
でいけるよ
156:デフォルトの名無しさん
09/01/24 15:15:23
ほんとだ、こっちのが短くていいですね。
157:デフォルトの名無しさん
09/01/24 15:27:24
struct b::rdm() を virtual にするなら template にする意味は無いと思うのだけれども・・・。
struct Q { // non template version
b * t;
Q( b * const t_) : t( t_ ? t_ : new b ){}
~Q() { /* Do you want to delete t ? */
int rdm() { return t->rdm();}
};
でいいでしょ。
ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。
158:デフォルトの名無しさん
09/01/24 16:08:53
単に左辺を書かなくても良くなるぐらいの気持ちで書き直したんですが
そもそもtenmplate無くても動きますね・・難しいなぁ
ある意味、template使わなくてもポリシーベースのプログラミングが出来るわけですね
あえてtemplateを使う利点が整理できてないので考えてみます。
>ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。
シンプルながら、これは説得力ありますね
159:デフォルトの名無しさん
09/01/24 16:43:24
>>155-156
R<r> a;でいいじゃない。
160:157
09/01/24 17:11:30
>>158
> あえてtemplateを使う利点が整理できてないので考えてみます。
157 では、t->rdm() は、コンパイラによって必ず仮想関数呼び出しコードが出力される。
テンプレートバージョンでは、定数を返す場合などには、もしかしたらコードは全く無くなるかもしれない。
153 程度で大げさな、と思うかもしれないが、これもメタプログラミングだ。
実行時に通過するコードではなく、コンパイルで出力されるコードを、引数で変えることが出来るから。
C のプリプロセッサマクロでも出来るけど、C++ template は型チェックとそこから派生する特殊化された型の選択が強み。
> シンプルながら、これは説得力ありますね
157 の Q のデストラクタを見てみて。
あと、メモリ消費量が減るかも。
ところで、154 の記法の問題は、cl, bcc, gcc で試したけど、
R<r> a( (r)r() );
が一番互換性が高いようだ。
もちろん 159 でいいんだけどw 引数を明示したいならね。
161:デフォルトの名無しさん
09/01/24 18:32:50
> R<r> a( (r)r() );
たまたま‘r’という短い名前だからそれでいいかもしれんが、
名前が長かったり、さらにネストしたテンプレートクラスだったりすると
書くのも面倒だよ。
他にも
R<r> a = R<r>(r());
とか考えられるけど、やっぱり
R<r> a((r()));
が楽だと思うけどね。
162:デフォルトの名無しさん
09/02/14 00:35:29 BE:1969877186-2BP(0)
age
163:デフォルトの名無しさん
09/03/12 22:20:49
テンプレートの引数にテンプレート渡せるのか~知らなかった。
これで大分やれることが広がったぜ。ウヒヒ
ていうか、テンプレートの完全な仕様ってどこに行けばみれるの?
164:デフォルトの名無しさん
09/03/12 22:27:47
>>163
ちょうどこっちでその話があったところ。
スレリンク(tech板:758-767番)