[表示 : 全て 最新50 1-99 101- 2chのread.cgiへ]
Update time : 05/09 14:21 / Filesize : 39 KB / Number-of Response : 165
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C++/TemplateMetaProgramming



1 名前:デフォルトの名無しさん [2008/02/16(土) 12:45:02 ]
・ここはC++のテンプレートメタプログラミング専用スレです。
・なかったので立てました。
・前にもあったような気がするけど気にしない。
・次期C++(0x) boost STLの話題も、TMPに関係するならここにどうぞ。

仲良く使ってね。

128 名前:デフォルトの名無しさん mailto:sage [2008/06/01(日) 19:09:24 ]
どんな数値でもいいから割り当ててしまえば二分探索の恩恵を受けられるってことだろ

129 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 02:49:12 ]
>>126
やはり無理なんですかね。
アドレスを得られるのはコンパイルのテンプレートの展開等の後の段階になるので無理だと思うのですが。

>>127
>>125で書いてある通り,型の集合の中に同じ型が含まれないようにすることが目的なので
boost::mpl::uniqueする前に同じ型が連続して並ぶようにboost::mpl::sortの結果が返ればよいのです。
ですので割り当てたい数字は型毎にユニークであれば何でもよいのです。アドレスもOK養豚場です。

>>128
二分探索を使って同じ型を消す処理をしてもO(n*log(n))で計算できそうですね。
そういう方法は考えていませんでした。

130 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:ヽ・´∀`・,,)っ━━━━━━━┓ mailto:sage [2008/07/09(水) 14:39:37 ]
>>124
静的(コンパイル時完全評価)だけどな。

VIPのスレで昔テンプレートでアッカーマン関数の問題解こうとしてドツボにハマった奴がいた。

132 名前:デフォルトの名無しさん [2008/07/16(水) 20:46:07 ]
『Modern C++ Design―ジェネリック・プログラミングおよびデザイン・
パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series) 』

ってのを読んでいる素人だけど、69ページのMostDerivedってのが
マジ分からん。今日、朝、昼、晩を合計で4時間ぐらい考えたんだが
どういう流れでこれで継承関係でいちばんの派生なのを特定できるのか
分からん。誰か分かる人いませんか?

133 名前:デフォルトの名無しさん [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/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 名前:デフォルトの名無しさん mailto:sage [2008/08/30(土) 14:17:24 ]
ttp://www.fides.dti.ne.jp/~oka-t/cpplab-tips-1.html に
ローカルクラスの静的関数は関数テンプレートの引数に指定可能というのがあるのですが、
ローカルクラスのクラス内クラスの場合どうなりますか?
役立たず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 名前:デフォルトの名無しさん mailto:sage [2008/08/30(土) 15:00:49 ]
VCだと言語拡張を有効にすることで関数内構造体もテンプレート引数に渡せてしまう。
俺はそれが嫌で言語拡張を無効にしてる。



137 名前:デフォルトの名無しさん mailto:sage [2008/08/30(土) 16:07:38 ]
>136
サンクス。無効にすると両方ともNGになりますね。
言語拡張を無効にすると色々なライブラリが使い物にならなくなるから、
さすがにそこまでストイックにはなれないなぁ……


138 名前:デフォルトの名無しさん mailto:sage [2008/08/31(日) 17:08:18 ]
言語拡張機能が使用された場合に警告を出すってオプションがあったと
思うんで、取り合えずそれONにしとけば?

139 名前:デフォルトの名無しさん mailto:sage [2008/08/31(日) 17:37:41 ]
そんなもの存在しません。

140 名前:デフォルトの名無しさん [2008/10/14(火) 17:41:25 ]
工エエェェ(´д`)ェェエエ工工

141 名前:デフォルトの名無しさん mailto:sage [2008/10/18(土) 22:01:41 ]
template <template <class Created> class CreatePolicy>

これのtemplate <class Create>部分の採用がヨクワカラナイ
どこかに良い説明のってないっすか

142 名前:デフォルトの名無しさん mailto:sage [2008/10/19(日) 02:40:29 ]
とりあえず検索用語だけ
template-template-parameters

143 名前:デフォルトの名無しさん mailto:sage [2008/10/24(金) 23:27:12 ]
class Hoge {
template <int X> void Fuga() {...}
};

テンプレート引数Xの値を、静的な値として集めることってできますか?
具体的には、呼び出されたFugaのうち、最も大きいXを取得して、別のクラステンプレートに渡すとか。

144 名前:デフォルトの名無しさん mailto:sage [2008/10/26(日) 01:21:18 ]
>>143
パッとみて無理っぽいうえにコンパイル単位をまたぐ場合を考えるとさらに無理っぽい。

145 名前:デフォルトの名無しさん mailto:sage [2008/10/30(木) 20:35:00 ]
(´;ω;`)

146 名前:デフォルトの名無しさん mailto:sage [2008/11/26(水) 04:36:26 ]
>>142
横だけど、meta templateでググっても見つからなく困っていたので助かった。
そういう用語だったのか…



147 名前:99 [2009/01/12(月) 20:40:07 ]
まいど。

どうしても欲しくなったのでマルチメソッドを実装したんだけど、もっと効率的になる改善点てあります?
(詳細)ttp://cvs.sourceforge.jp/view/siki/siki/src/holder.hpp?rev=1.1&view=markup
(解説)ttp://fiercewinds.net/siki/pub/2009/01/12_191240/
解説がクソなのは置いといて下さい。

もっと良い実装があればそれも紹介して欲しいです。

個人的には
・いちいち登録しなきゃいけないのが面倒。
・トランポリン関数を保持する配列が疎になるのでメモリ効率が悪そう……
というところが気になるところです。



148 名前:99 mailto:sage [2009/01/13(火) 00:44:59 ]
ちょっとだけ >147を修正。
登録をヘルパークラスに任せることにしました。少しはスマートに見えるけど、受け入れる型を
全部登録しなきゃいけないのは変わらず……

色々と考えてみたけど、どうやっても仮想関数に型情報は渡せなさそうね……。


149 名前:99 mailto:sage [2009/01/13(火) 01:15:20 ]
リンク間違えてたので修正します。
(詳細)ttp://cvs.sourceforge.jp/view/siki/siki/src/holder.hpp?view=markup

150 名前:デフォルトの名無しさん mailto:sage [2009/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 名前:デフォルトの名無しさん mailto:sage [2009/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 mailto:sage [2009/01/19(月) 21:33:25 ]
>>151
ありがとう。参考にします。

153 名前:デフォルトの名無しさん mailto:sage [2009/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 名前:デフォルトの名無しさん mailto:sage [2009/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 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 14:55:23 ]
>>154
>  R<r> a(r()); //error
R<r> a((r()));
でいけるよ

156 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 15:15:23 ]
ほんとだ、こっちのが短くていいですね。



157 名前:デフォルトの名無しさん mailto:sage [2009/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 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 16:08:53 ]
単に左辺を書かなくても良くなるぐらいの気持ちで書き直したんですが
そもそもtenmplate無くても動きますね・・難しいなぁ
ある意味、template使わなくてもポリシーベースのプログラミングが出来るわけですね
あえてtemplateを使う利点が整理できてないので考えてみます。

>ポインタじゃなくて、値のコピーのほうが、いろいろいいよ。
シンプルながら、これは説得力ありますね

159 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 16:43:24 ]
>>155-156
R<r> a;でいいじゃない。

160 名前:157 mailto:sage [2009/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 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 18:32:50 ]
> R<r> a( (r)r() );

たまたま‘r’という短い名前だからそれでいいかもしれんが、
名前が長かったり、さらにネストしたテンプレートクラスだったりすると
書くのも面倒だよ。

他にも
 R<r> a = R<r>(r());
とか考えられるけど、やっぱり
 R<r> a((r()));
が楽だと思うけどね。

162 名前:デフォルトの名無しさん mailto:age [2009/02/14(土) 00:35:29 BE:1969877186-2BP(0)]
age

163 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 22:20:49 ]
テンプレートの引数にテンプレート渡せるのか〜知らなかった。
これで大分やれることが広がったぜ。ウヒヒ
ていうか、テンプレートの完全な仕様ってどこに行けばみれるの?


164 名前:デフォルトの名無しさん mailto:sage [2009/03/12(木) 22:27:47 ]
>>163
ちょうどこっちでその話があったところ。
pc11.2ch.net/test/read.cgi/tech/1234420483/758-767






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](*・∀・)<39KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef