Generic Programming with C++ Template
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG参考図書:
Modern C++ Design
Andrei Alexandrescu, Addison-Wesley, ISBN:0-201-70431-5
(訳書: ピアソン・エデュケーション, ISBN:4-89471-435-3)
http://cseng.aw.com/book/0,,0201704315,00.html
Generic Programming - STL による汎用プログラミング
Matthew H. Austern, ASCII, ISBN:4-7561-3441-6
関連スレッド:
C++相談室 Part3
http://pc.2ch.net/test/read.cgi/tech/1003832761/
STL スレッド
http://pc.2ch.net/test/read.cgi/tech/1004287394/
0514デフォルトの名無しさん
NGNGクリティカルな問題が無くならないね。
もうちょっと単純な仕様にすればいいのに。>テンプレート
0515デフォルトの名無しさん
NGNGQ: 他のC++ ツールで、より標準に適合しているものはありますか?
JON CAVES: はい、Visual C++よりも標準に適合するC++ コンパイラはあります。
1つの例は、私が100%適合していると信じるEdison Design Group (EDG)によるコンパイラです。
ただし、このコンパイラはWindows プラットホームではあまり利用できませんが。
Windows プラットホームではやはり、Visual C++が最も標準に適合するコンパイラの1つです。
0516デフォルトの名無しさん
NGNG一長一短ではあるけど、
gcc3 、CodeWarrior7、 bcc5.6 (C++Builder) 辺りは
VC6よりは遙かに標準に近い気がする。VC.NETだとどうなんだろ?
それに、EDGのフロントエンドも100%とは思えないが…。
0517デフォルトの名無しさん
NGNGテンプレートパラメータがサポートされた程度。
てゆうかLokiコンパイルできません。
0518デフォルトの名無しさん
NGNG>テンプレートの部分的な特殊化
はどうなの?
0519デフォルトの名無しさん
NGNG>>513 はVC.NETでの話。
0520デフォルトの名無しさん
NGNGその優先順位の判断にパターンマッチングやらなんやらが必要らしいです。
しかしModernC++によって部分的な特殊化がほぼ別物といっても良いくらい
飛躍的な表現力の向上につながることが明らかにされたわけなので
今後積極的にサポートされていく可能性は高いでしょう。
0522デフォルトの名無しさん
NGNGあれでコンパイラメーカーの奮起を期待したいところだね。
VC++に関してはどうなんだろう。MSやる気あんのかなぁ。。
個人的には.netでのアクロバットなテンプレートサポートに
期待してるけどね。
0523デフォルトの名無しさん
NGNGAdobe Acrobat.NET(テンプレート付き)
0524デフォルトの名無しさん
NGNG0525名無しさん
NGNG0526デフォルトの名無しさん
NGNG0527508
NGNG拡大反転透過楕円半透明コピーが出来たときには感動した!!
馬鹿正直に書いてたら数千〜数万行のコードがたったの500行ですんだ、すごいYO!!
0528デフォルトの名無しさん
NGNG公式サイトからダウンロードしたソースに、バグらしきものを発見しました。
該当個所は、第四章で紹介されているFixedAllocatorのVicinityメソッドです。
SmallObj.cpp の中で以下のようになっていますが(左は行番号)、
271: Chunk* lo = deallocChunk_;
272: Chunk* hi = deallocChunk_ + 1;
273: Chunk* loBound = &chunks_.front();
274: Chunk* hiBound = &chunks_.back() + 1;
もし deallocChunk_ が &chunks_.back() と同じ値であった場合、
290: if (p >= hi->pData_ && p < hi->pData_ + chunkLength)
この hi が指しているのは範囲外の要素となってしまいます。
これは既知のバグなのでしょうか。
参考までに VicinityFind メソッドを全文引用しておきます。
264:FixedAllocator::Chunk* FixedAllocator::VicinityFind(void* p)
265:{
266: assert(!chunks_.empty());
267: assert(deallocChunk_);
268:
269: const std::size_t chunkLength = numBlocks_ * blockSize_;
270:
271: Chunk* lo = deallocChunk_;
272: Chunk* hi = deallocChunk_ + 1;
273: Chunk* loBound = &chunks_.front();
274: Chunk* hiBound = &chunks_.back() + 1;
275:
276: for (;;)
277: {
278: if (lo)
279: {
280: if (p >= lo->pData_ && p < lo->pData_ + chunkLength)
281: {
282: return lo;
283: }
284: if (lo == loBound) lo = 0;
285: else --lo;
286: }
287:
288: if (hi)
289: {
290: if (p >= hi->pData_ && p < hi->pData_ + chunkLength)
291: {
292: return hi;
293: }
294: if (++hi == hiBound) hi = 0;
295: }
296: }
297: assert(false);
298: return 0;
299:}
0529直してみた
NGNG265:{
266: assert(!chunks_.empty());
267: assert(deallocChunk_);
268:
269: const std::size_t chunkLength = numBlocks_ * blockSize_;
270:
271: Chunk* lo = deallocChunk_;
272: Chunk* hi = deallocChunk_; // ココ
273: Chunk* loBound = &chunks_.front();
274: Chunk* hiBound = &chunks_.back() + 1;
275:
276: for (;;)
277: {
278: if (lo)
279: {
280: if (p >= lo->pData_ && p < lo->pData_ + chunkLength)
281: {
282: return lo;
283: }
284: if (lo == loBound) lo = 0;
285: else --lo;
286: }
287:
294: if (++hi == hiBound) hi = 0; // ココ
288: if (hi)
289: {
290: if (p >= hi->pData_ && p < hi->pData_ + chunkLength)
291: {
292: return hi;
293: }
295: }
296: }
297: assert(false);
298: return 0;
299:}
0530デフォルトの名無しさん
NGNG0531デフォルトの名無しさん
NGNG0532528
NGNGおー、これだとたしかになおってそうですね。
つうか、オレもなおしちゃったけど。
もし未知のバグなら、報告したほうがいいんですかね。英語わかんねえけど。
>>530
がんばって行番号つけたのにッ! BASICを使ってた思い出に浸っていたのにッ!
オレの思い出をこわさないでー!
>>531
んなわけねえだろ。だいたい0行目なんて存在しねえんだよ。
テメエはCのやりすぎだ。一日二回くらいにしといたほうがいいぞ。
0533デフォルトの名無しさん
NGNGなんか、ギャップにワラタ
0534デフォルトの名無しさん
NGNG訳者のページに行ってみてはどうか。
オンラインで直ってないなら未知と思われるので。
0535デフォルトの名無しさん
NGNGme fix bug. this patch
とか書いてdiff結果張り付けてメールとか。
0536528
NGNGでも英語なので、あいかわらずよくわかりませんです。
http://www.kuro5hin.org/story/2002/4/5/82022/76326
>>533
ギャップってアレか。テキストエディタつくるときに使うとか聞いたことあるやつ。
それはギャップバッファだー! ちゅどーん!
>>534
訳者の方のページは見てみましたが、誤植の情報しかないようでした。残念賞。
>>535
出会い系サイトじゃないと、知らない人にメールなんて出せませんよ。怖すぎ。
しかも外人さんだし。やけに深呼吸ばかりしてそうだし(洋モノビデオの見すぎ)。
0537デフォルトの名無しさん
NGNGワロタ。
0538デフォルトの名無しさん
NGNG0539デフォルトの名無しさん
NGNG0540528
NGNGあら、雰囲気悪くなっちゃった? ユーモアってやつをわかってねえなあ。
ほれ、良書って言われる類の書籍には、たいていアメリカンジョークが書いてあるじゃん。
それもすっげーつまんないやつ。立派なプログラマなら、それで笑えるようになろうぜ。
理想としては、>>537の人みたいにソースコードを見ただけで
笑いがこみ上げてくるレベルを目指すべし。
0541デフォルトの名無しさん
NGNGキエロ
0542デフォルトの名無しさん
NGNG0543デフォルトの名無しさん
NGNG528のはそれ未満なので笑えません。
0544デフォルトの名無しさん
NGNGそれはあり得ない。
常に541>540である
0545デフォルトの名無しさん
NGNG0546デフォルトの名無しさん
NGNG0547デフォルトの名無しさん
NGNG単位は?
(ケルビンじゃないよな)
0548デフォルトの名無しさん
NGNGなんか、某駄スレのJohnに酷似しているし。
0549デフォルトの名無しさん
NGNG0550デフォルトの名無しさん
NGNGコンパイル速度激しく遅くなったんですが(;´Д`)
PCHにいれても入れなくても変わらず
自業自得ですけど・・・死ねるほどおそひ・・・VC.NET・・・
0551デフォルトの名無しさん
NGNG0552デフォルトの名無しさん
NGNGインライン実装するべきじゃない。
デメリットのほうが大きい。
素直にテンプレートの具体的な特殊化か
ポリモフィズムを使用するべし。
0553デフォルトの名無しさん
NGNG昔の実装と違ってinlineはregisterと同じくもはやヒントでしかないし……。
そうカリカリせんでもいいんじゃない?
(暗黙のstticの意味を除けば。)
0554デフォルトの名無しさん
NGNG0555デフォルトの名無しさん
NGNGVC++の場合ちょっとでも大きいとインライン展開してくれないようです
3行くらいでもわりと複雑な計算してると展開されません
チョー速度が要求されるところだったから__forceinline使いましたが
0556デフォルトの名無しさん
NGNG依存関係のある全てのソースにリコンパイルがかかる。
また、インライン展開されなくとも複数の実体が生成される可能性もある。
そもそもインライン展開の判断自体、処理系依存である。
ちっこいプロジェクトなら問題ないかもしれんが
大規模ではちょっとした手抜きの割に被害はでかい。
テンプレートの使い方とその設計手法をまともに考えれば
クソでかい関数はできないはず。
0557デフォルトの名無しさん
NGNG0558デフォルトの名無しさん
NGNGinlineとexportしてない(できない)templateとtemplateの明示的特化って
別物じゃないの?
0559デフォルトの名無しさん
NGNG出直そう
0560552
NGNG>インライン実装するべきじゃない。
>デメリットのほうが大きい。
ここは一般論でその理由は>>556
>素直にテンプレートの具体的な特殊化か
>ポリモフィズムを使用するべし。
こっちは>>550に対してアドヴァイスしたつもりだった。
言葉足らずスマン。
テンプレート関数をexportできる処理系はまだ見たこと無いので
無いものとして話してる。
補足:
>テンプレートの具体的な特殊化
具体的な特殊化でテンプレート引数がすべて決まれば
普通のクラスと同じように非インライン関数として書ける。
テンプレートの用途からするとほとんど使えないテクだが・・
0561デフォルトの名無しさん
NGNG何が問題なのでしょうか?g++ならば通るんですが・・・。
template<typename T, typename U> struct test {};
template<class T> struct test<int,T> {};
0562デフォルトの名無しさん
NGNGVC++は諦めてください
0564デフォルトの名無しさん
NGNGマジです
0566デフォルトの名無しさん
NGNG.NETでもダメです。
正直がっかりでしたがVC8に期待しましょう。
0568デフォルトの名無しさん
NGNG0569デフォルトの名無しさん
NGNG0570デフォルトの名無しさん
NGNG0571デフォルトの名無しさん
NGNG0572デフォルトの名無しさん
NGNG0573デフォルトの名無しさん
NGNG0574デフォルトの名無しさん
NGNG0575デフォルトの名無しさん
NGNGhttp://www.objectcentral.com/
0576VC6に乗せたい
NGNGtemplate <class TList>
struct Length
{
enum { value = 1 + Length<TList::Tail>::value };
};
template <> struct Length<NullType>
{
enum { value = 0 };
};
template <class TList, unsigned int i>
struct TypeAt
{
template<int cnt>
struct isEnd
{
typedef typename TypeAt<TList::Tail, cnt-1>::Result type;
};
template<> struct isEnd<0>
{
typedef typename TList::Head type;
};
typedef typename isEnd<i>::type Result;
};
こういう風に書き換えればTypeListを使うことができるようになった。
既出ならスマソ
0577デフォルトの名無しさん
NGNGなんだかわからんけど、よくやった!
次もこの調子でたのむ。
0578デフォルトの名無しさん
NGNG0579デフォルトの名無しさん
NGNGよくやった!
ただ、
不明な型が厳密にひとつしかないクラステンプレートなら
部分的な特殊化を使わずに実装できるんだが
TypeListにはそうでない機能がいくつかあるんだよね。
0580デフォルトの名無しさん
NGNGって言ってもtemplateなstatic変数が作れないだけですから、
マクロ作って個々にインスタンスを作ってやっただけですけど。
で、ためしにLoki::SingletonWithLongevity使ってみたら
GetLongevityの戻り値が大きいほうから先に削除されちゃうんです。
ここでまたぶち切れですよ。
ModernにはGetLongevityの戻り値が小さいほうから削除されるように書かれているのに。
これはどう解釈したら言いのでしょう。
0581デフォルトの名無しさん
NGNGVC++でSelectをなんとか出来ませんか?
0582VC6に乗せたい
NGNGそれはさておき。
VC++6.0は、ご承知のようにクラステンプレートの部分的な特殊化を
サポートしていません。
しかし、クラステンプレートの完全な特殊化はサポートされています。
[VC6で使えない例]
template <class TA, class TB>
struct baa{};
template <class TA>
struct baa<TA, int> ← すでに定義されているというエラーが出る
{};
[VC6で通る例]
template <class T>
struct baa{};
template <> struct baa<double> {};
あるいは、
template <class TA, class TB>
struct tee{};
template <> struct tee<double, int> {};
これだけなら大したことはできないのですが、
これをTypeAtのように、クラス内クラスで使うことで、
事実上の部分特殊化を掛けることができるようになります。
現在、手元でIndexOf まで仕上げました。
私はファンクタとダブルディスパッチを使いたいと思っているので、
それらの実装を目指すことにします。
0583デフォルトの名無しさん
NGNGおぉぉ!
template< A, B, C >
の
Aだけ特殊化は出来ないから
template< A > class{ template< B, C > }
にしてAを特殊化するんですね!
Select行ってみます!
0585583
NGNGtemplate< A, B, C > struct
{
template< A > struct
{ //↑ここを特殊化するんですね
}
}
0587VC6に乗せたい
NGNGあのように作り方を明記すると、考えが整理できるものですね。
>>576で載せたテンプレートも、ガイドラインに沿った命名に書き換えました。
template <class TList, unsigned int index,
typename DefaultType = NullType>
struct TypeAtNonStrict
{
template <class tmpTList>
struct tmp2TypeAt
{
template <unsigned int cnt>
struct tmp1TypeAt
{
typedef TypeAtNonStrict<tmpTList::Tail, cnt-1, DefaultType>::Result Result;
};
template <> struct tmp1TypeAt<0>
{
typedef tmpTList::Head Result;
};
typedef tmp1TypeAt<index>::Result Result;
};
template <> struct tmp2TypeAt<DefaultType>
{
typedef DefaultType Result;
};
typedef tmp2TypeAt<TList>::Result Result;
};
このコードで、コンパイル、テスト動作ができることは確認しております。
願わくば、この勢いで TypeList.h で定義されている
テンプレート群をVC6仕様に書き換える作業にご協力願いたい。
正直、一人ではきついので。
0588デフォルトの名無しさん
NGNGで、今どこまで出来てるの?
協力しようにも何が出来てて何がまだなのか分からんと。
ただ、漏れ VC++ 持ってねぇんだよなぁ・・・
0589デフォルトの名無しさん
NGNG>>587の
下から6行目
> template <> struct tmp2TypeAt<DefaultType>
↓
> template <> struct tmp2TypeAt<NullType>
だと思います。
0590VC6に乗せたい
NGNG本業もあるため、平日は遅々とした進度になるかと思われます。
できそうなところからどんどん発表していくつもりです。
あと、>>589の指摘ですが、原著の作者の実装をそのまま置き換えたため、
そのようになっております。元ソースと比較してみてください。
なお、先日から取り組んでいる Typlist 型関数は、
数値関数に置き換えれば、このようになります。
Result TypeAtNonStrict(class TList, int index,
class DefaultType = NullType)
{
if(TList != DefaultType)
{
if(index != 0)
{
return TypeAtNonStrict(TList.Tail, index-1, DefaultType);
}
else
{
return TList.Head;
}
}
else
{
return DefaultType;
}
};
元ソースよりもいくらか手続きっぽくなってるのかも。
0591デフォルトの名無しさん
NGNG0592VC6に乗せたい
NGNGResult TypeAtNonStrict(class TList, int index,
class DefaultType = NullType)
{
if(TList != DefaultType)
{
if(index != 0)
{
return TypeAtNonStrict(TList.Tail, index-1, DefaultType);
}
else
{
return TList.Head;
}
}
else
{
return DefaultType;
}
};
0593583
NGNG今MostDerived終わりました。後でどっかでマージしませう
あとtmpじゃ分かりにくいので名前付け方法を決めたほうがいいと思います。
私は
template <class TList, unsigned int index,
typename DefaultType = NullType> struct TypeAtNonStrict
{
template <class tmpTList> struct SelectTList
{
template <unsigned int cnt> struct SelectIndex
{
hogehoge...
};
};
typedef SelectTList<TList>::SelectIndex<index>::Result Result;
};
のようにしました
0594デフォルトの名無しさん
NGNG0595583
NGNGつーか使っててすげーです、Lokiマンセー!!!
0596デフォルトの名無しさん
NGNG素晴らしい。
第二版に日本人の名を連ねられるか??
期待して待つ!
0597デフォルトの名無しさん
NGNG漏れ私的に使いたかったTypeTraitsの移植に挑戦してみようかな・・・
0599583
NGNG0600583
NGNGもしかしてtypelist.h終わったじゃん。
どっかにウプしよーぜ!
0601デフォルトの名無しさん
NGNG0602デフォルトの名無しさん
NGNGsourceforge.netだ
0603583
NGNG使い方分からん・・・(´д`;
編集済みtypelist.hとtypemanip.h、
VC++用に改造したsingleton.hが入ってます。
http://www68.dns.ne.jp/~bbs2/upload3/helen/OB00011454.zip
VC++.NETで作ったので、VC++6.0で動かなかったらゴメソ
なにぶん以前は動いてなかったので、typelist.hとtypemanip.hが元と同じように動作するかは確認できてません。
特にtypemanip.hのConversionが、exists2Wayが元と違う方法を使ってるので、その辺でばぐるかも。
編集後のSingletonHolderは残念ながら元と全く同じように使うことは出来ません、
これを使うときは、
プロジェクト内のCPPファイル内でImplementLokiSingletonマクロを使って
SingletonHolderのstaticメンバ変数の実体を作ってちょ
とにかく576は間違いなく神だな・・・
神の啓示を受けた気分だ。
0604583(゚ Д ゚ ;)・・・・
NGNGhttp://www.geocities.com/rani_sharoni/LokiPort.html
0605VC6に乗せたい
NGNG>>603は早速ダウンロードして、すべてチェックしました。
今のところ、VC6でも正常に動作しているようです。
typename とはこういうものだったのですか。
これを知らずにAppendの実装がうまくいかず、一時中断していたのですが。
知らぬではどうにもならぬですね。まだまだ修行が足りないです。
勉強になります。
0606583
NGNG0607583
NGNGやっぱりやってることはほとんど同じか・・・(鬱
(汚いと見えた)MakeTypeListやis_TypelistはLokiのバージョンアップで追加されたものかな?
0608VC6に乗せたい
NGNG結局、VC6にはtypename 指定をしないと、
template<typename Head, typename Tail>
Typelist<Head, Tail>
と
NullType の区別がつかないようなのです。
VC.NET用はともかく、VC6用は、ここで新規開発しないといけないかも。
0609597
NGNGダメですた。
ポインタの特殊化がどーーーしてもできまへん。
と思ったら>>604 で見事に実装されてますた。
悔しいやら嬉しいやら。
ともかく念願のTypeTraitsが手に入りますた。
ありがとうございます。
0610597
NGNGなぜか前から関数テンプレートのポインタ等の特殊化を
サポートしてるんだよな・・。
その調子でクラステンプレートも実装してホスィ
0612デフォルトの名無しさん
NGNGこれがあるとがぜん使う気が起きるね!
0613VC6に乗せたい
NGNG>>609 LokiPort の MakeTypeList は単体で動作するようです。
>>583氏のヘッダに移植できました。
あと、うっかりサンプルソースでReverseを呼び出すのを忘れていたのですが、
こいつがエラーが出てコンパイラにとおりません。(VC6)
ガイドライン通りにちゃんと書かれているようなのですが。原因はまだ不明です。
■ このスレッドは過去ログ倉庫に格納されています