5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

Generic Programming with C++ Template

1 :デフォルトの名無しさん:01/12/17 21:45
C++ による Generic Programming の話をしよう。

参考図書:
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/

576 :VC6に乗せたい:02/06/03 02:06
VS.NETが買えない貧乏人の私としては、VC6で何とか動かしてみたい。

template <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を使うことができるようになった。
既出ならスマソ

577 :デフォルトの名無しさん:02/06/03 02:08
>>576
なんだかわからんけど、よくやった!
次もこの調子でたのむ。

578 :デフォルトの名無しさん:02/06/03 02:31
>>576は神!!

579 :デフォルトの名無しさん:02/06/03 09:45
>>576
よくやった!

ただ、
不明な型が厳密にひとつしかないクラステンプレートなら
部分的な特殊化を使わずに実装できるんだが
TypeListにはそうでない機能がいくつかあるんだよね。

580 :デフォルトの名無しさん:02/06/03 10:37
VC++で無理やりSingletonHolderを動くようにしたんです。
って言ってもtemplateなstatic変数が作れないだけですから、
マクロ作って個々にインスタンスを作ってやっただけですけど。
で、ためしにLoki::SingletonWithLongevity使ってみたら
GetLongevityの戻り値が大きいほうから先に削除されちゃうんです。
ここでまたぶち切れですよ。
ModernにはGetLongevityの戻り値が小さいほうから削除されるように書かれているのに。
これはどう解釈したら言いのでしょう。

581 :デフォルトの名無しさん:02/06/03 10:52
>>576
VC++でSelectをなんとか出来ませんか?

582 :VC6に乗せたい:02/06/03 17:07
昼頃出先で書き込もうとしたら、串が2ch鯖に知られてて書き込めず、激しく鬱。
それはさておき。

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 まで仕上げました。
私はファンクタとダブルディスパッチを使いたいと思っているので、
それらの実装を目指すことにします。

583 :デフォルトの名無しさん:02/06/03 17:21
>>582
おぉぉ!

template< A, B, C >

Aだけ特殊化は出来ないから
template< A > class{ template< B, C > }
にしてAを特殊化するんですね!
Select行ってみます!

584 :583:02/06/03 17:56
Selectはできたけんども
TypeAtNonStrictで見事に撃沈・・・
完成したら作者に報告とともにどっかにウプしてくれ・・・>>583

585 :583:02/06/03 17:59
583を訂正

template< A, B, C > struct
{
 template< A > struct
 { //↑ここを特殊化するんですね
 }
}

586 :584(´д`;:02/06/03 18:01
584を訂正
ポインタが・・・>>583じゃ無くて>>582だ。
・・・鬱だ・・・氏んでくる

587 :VC6に乗せたい:02/06/03 18:43
>>583殿。>>582で示したガイドラインに沿ってTypeAtNonStrictを書いてみました。

あのように作り方を明記すると、考えが整理できるものですね。
>>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仕様に書き換える作業にご協力願いたい。
正直、一人ではきついので。


588 :デフォルトの名無しさん:02/06/03 19:10
>>587
で、今どこまで出来てるの?
協力しようにも何が出来てて何がまだなのか分からんと。

ただ、漏れ VC++ 持ってねぇんだよなぁ・・・

589 :デフォルトの名無しさん:02/06/03 19:18
強力はおしまんですよ、TypeAtNonStrictすらできなかった漏れが役に立てるかどうかはわからんですけど、
>>587
下から6行目
> template <> struct tmp2TypeAt<DefaultType>

> template <> struct tmp2TypeAt<NullType>
だと思います。


590 :VC6に乗せたい:02/06/03 19:52
>>588殿。恥ずかしながら、まだ IndexOf を実装しただけです。
本業もあるため、平日は遅々とした進度になるかと思われます。
できそうなところからどんどん発表していくつもりです。

あと、>>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;
}
};

元ソースよりもいくらか手続きっぽくなってるのかも。


591 :デフォルトの名無しさん:02/06/03 19:53
age

592 :VC6に乗せたい:02/06/03 19:54
しまった。タブの置き換えを忘れていました。スマソ

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;
  }
};


593 :583:02/06/03 20:05
とりあえず私はtypelist.hの下から行きます。
今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;
};

のようにしました

594 :デフォルトの名無しさん:02/06/03 20:22
す、すげー。あんたら、すげーよ。完成したら、ぜひ使わせてもらうよ! がんばってっ!

595 :583:02/06/03 20:28
ReplaceとReplaceAll終わりました
つーか使っててすげーです、Lokiマンセー!!!

596 :デフォルトの名無しさん:02/06/03 20:46
目から鱗すぎます。
素晴らしい。
第二版に日本人の名を連ねられるか??
期待して待つ!

597 :デフォルトの名無しさん:02/06/03 20:48
あー
漏れ私的に使いたかったTypeTraitsの移植に挑戦してみようかな・・・

598 :583:02/06/03 20:51
Erase以降全て終わりますた
>>597
人が作ったものは作り直したくないので、終わったらここに報告してね。

599 :583:02/06/03 20:52
漏れがLokiと格闘してる間にイタリア1点取ってるし・・・(´д`;

600 :583:02/06/03 20:54
うぉ!
もしかしてtypelist.h終わったじゃん。
どっかにウプしよーぜ!

601 :デフォルトの名無しさん:02/06/03 20:57
sourceforge.comだと世界中から見つかりやすげ

602 :デフォルトの名無しさん:02/06/03 20:58
>>601
sourceforge.netだ

603 :583:02/06/03 21:22
>>601-602
使い方分からん・・・(´д`;

編集済み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は間違いなく神だな・・・
神の啓示を受けた気分だ。

604 :583(゚ Д ゚ ;)・・・・:02/06/03 22:08
もしかして・・・車輪の再発明でしたか?

http://www.geocities.com/rani_sharoni/LokiPort.html

605 :VC6に乗せたい:02/06/03 22:09
おおおっ! ちょっと離席していた間にもう終わったのですか。すげー!
>>603は早速ダウンロードして、すべてチェックしました。
今のところ、VC6でも正常に動作しているようです。

typename とはこういうものだったのですか。
これを知らずにAppendの実装がうまくいかず、一時中断していたのですが。
知らぬではどうにもならぬですね。まだまだ修行が足りないです。
勉強になります。

606 :583:02/06/03 22:13
LokiPortよりも漏れらのやつのほうが美しいようだ、良かった良かった。

607 :583:02/06/03 22:23
おりょ?
やっぱりやってることはほとんど同じか・・・(鬱
(汚いと見えた)MakeTypeListやis_TypelistはLokiのバージョンアップで追加されたものかな?

608 :VC6に乗せたい:02/06/03 22:51
>>583その「is_Typelist」が、VC6ではコンパイラに通らないです。
結局、VC6にはtypename 指定をしないと、
template<typename Head, typename Tail>
Typelist<Head, Tail>

NullType の区別がつかないようなのです。

VC.NET用はともかく、VC6用は、ここで新規開発しないといけないかも。

609 :597:02/06/03 23:14
>>598
ダメですた。
ポインタの特殊化がどーーーしてもできまへん。
と思ったら>>604 で見事に実装されてますた。
悔しいやら嬉しいやら。

ともかく念願のTypeTraitsが手に入りますた。
ありがとうございます。

610 :597:02/06/03 23:17
そういえばVCは
なぜか前から関数テンプレートのポインタ等の特殊化を
サポートしてるんだよな・・。
その調子でクラステンプレートも実装してホスィ

611 :583:02/06/03 23:29
>>608
漏れはVC.NETなのでLokiPortに満足してしまいますた。
続きはがんばってください。
何かあれば協力しますし。

612 :デフォルトの名無しさん:02/06/04 11:22
MakeTypeList age
これがあるとがぜん使う気が起きるね!

613 :VC6に乗せたい:02/06/04 12:40
>>608まあ今時VC6でなにかしようというのが、もう時代遅れなのかもしれないですが。
>>609 LokiPort の MakeTypeList は単体で動作するようです。
>>583氏のヘッダに移植できました。

あと、うっかりサンプルソースでReverseを呼び出すのを忘れていたのですが、
こいつがエラーが出てコンパイラにとおりません。(VC6)
ガイドライン通りにちゃんと書かれているようなのですが。原因はまだ不明です。

614 :デフォルトの名無しさん:02/06/04 16:01
このスレの前のほう見るとLokiをVCで通るようにするのは絶対無理って書かれてるな。
>>613はその発想力を大切にするといい。

615 :デフォルトの名無しさん:02/06/04 16:29
ModernC++のページでもセンセーショナルだと書かれてるね>604
出てきたのが今年の3月だから、タッチの差は僅かだ。

MakeTypeList も上のほうで無理言われてたけどあっさり実装されちゃってる
まるで魔法だ。
C++って奥深すぎる。鬱だ。

215 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.02 2018/11/22 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)