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/
0652デフォルトの名無しさん
NGNG#include <iostream>
int main(void)
{
int a;
__if_exists( a ){ std::cout << "a ハケーン" << std::endl; }
__if_not_exists( a ){ std::cout << "そんな変数無いです" << std::endl; }
}
こんな感じ
このままだと "a ハケーン" が表示される
int a;をコメントアウトすると "そんな変数無いです" が表示される
( ) 括弧の中は変数だけじゃなくて、任意のシンボルが入れられる。
もちろんメンバ関数も。
0653デフォルトの名無しさん
NGNGネイティブにも使えるけど、もしかしたらVC++.NETから新しく追加された機能かも
0654デフォルトの名無しさん
NGNG0655名無しさん
NGNGメンバー、メソッドでもOKなの?
0656デフォルトの名無しさん
NGNG0657デフォルトの名無しさん
NGNG(識別子をどうするかは、考えないといけないが)
0658デフォルトの名無しさん
NGNGコンパイラによるリフレクション? 規格はさすがに無理ぽそうだけど...
0659名無しさん
NGNGウヒャ─、これは便利、って例ある?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrfthe__if_existsstatement.asp
memberもOKなのね。しかし、なんじゃこりゃ? って感じ。
0660デフォルトの名無しさん
NGNGタグディスパッチがいらなくなるんじゃない
0661名無しさん
NGNGinline void advance(_Iterator& __i, _Distance __n) {
__if_exists( _Iterator::operator[]){ __i += __n; } // random
__if_exists( _Iterator::operator--){ if (__n >= 0) while (__n--) ++__i; else while (__n++) --__i; } // bi
// elseがないからtag抜きでforward iterator書きにくい。
}
こんな感じ?
0662デフォルトの名無しさん
NGNG0663デフォルトの名無しさん
NGNGコンパイラがコンパイルの前に置換をしてくれるんだよ。
プリプロセッサがやる単純な置換と違い、コンパイラが型チェックに
責任を持ってくれる。
0664デフォルトの名無しさん
NGNGTemplateはどういうときに使うのですか?
0665デフォルトの名無しさん
NGNGリストって知ってるよね?単方向でも双方向でも。
例えば、構造体Aと言う値を保持するリストのクラスを作ったとする。
これがなかなか便利で他のプログラムにも使いたい。
しかし、構造体Aは前のプログラム独自の物なので汎用性を持たせたい。
そこで、構造体Aの代わりにvoid *を持たせることにした。
しかし、これでは型キャストの嵐になるし、新しいノードを作るとき、自動的にデータ格納用の
メモリ領域を確保したり開放したりすることが困難になる。
next = new nextnode();
next.data = new ここを使う型が変わるたびに変更しなくてはならない。
そこでテンプレート。これは特定の抽象型を具体的な型に置換できる。
例えば、データ用の型をDATAとし、それをintと具体化すれば、
int型を扱うリストが出来るし、struct aaaと具体化すればaaa構造体のリストとなる。
0666デフォルトの名無しさん
NGNG0667デフォルトの名無しさん
NGNG抽象化する時
(メソッドとか関数とか)
0668613
NGNG激しくスレ違いに真面目にレス。2ちゃんねらーの鑑です。
私も見習わないと。
ということで真面目レスを追加しておきますと、
テンプレート(template)の萌芽はMFCのコンテナにも見られます。
(CMap、CListなど)
でもやはり、STLは一通り勉強しましょう。
ttp://www.wakhok.ac.jp/~sumi/stl/index.html
それから、Effective C++、More Effective C++を一通り読んで、
>>1 のModern C++ Design を買えば、
晴れてこのスレの住人に仲間入りです。
頑張りなされ。
0669デフォルトの名無しさん
NGNGいくらかかると思ってんのYO(`Д´)
0670デフォルトの名無しさん
NGNG全部持ってるYO!高かったけど仕方ないYO!
0671デフォルトの名無しさん
NGNG書籍にかけた金は、すぐに仕事実績で取り返せる(ちゃんと読めば)。惜しむな。
0672デフォルトの名無しさん
NGNGそう思いこみたいんですね :)
0673デフォルトの名無しさん
NGNG怖がりすぎー。
0674デフォルトの名無しさん
NGNG初期化するのはめんどくせー」ってことで、
WithInit< int , 600 > m_intvalue;
ちゅーよーなのを書いた。
ひょっとして、車輪を再発名した……?
勝手に600に初期化されるint ってこと?
0676age
NGNG"error C2516: 'Inner' : は正しい基本クラスではありません。"
を吐きます。
InnerInFunc は問題なく通ります。
これはC++の仕様?それともVC++の問題?
InnerInStruct も使えるように出来ないのでしょうか?
struct Base{ struct Inner{};};
template< typename T > struct Mid: public T{};
template< typename T > struct Sub
{
struct InnerInStruct: public Mid< T >::Inner{};
Sub()
{
struct InnerInFunc: public Mid< T >::Inner{};
}
};
int main(void)
{
Sub< Base > sub;
}
0677デフォルトの名無しさん
NGNG整数型でしか使えないじゃん。
0678デフォルトの名無しさん
NGNGg++3.1やbcc5.5.1では何ごともなく通ったよん
0680デフォルトの名無しさん
NGNGbool, int ,char , short, long , float, doubleと使えれば
充分じゃねーんすか?
0681デフォルトの名無しさん
NGNGEffective STLの第2項、「コンテナに依存しないコードという幻想に注意しよう」を
読んだ上で言ってます。
vector,deque,listってのは、しょせん実装の詳細なわけですから、最初っから
「汎用シーケンスコンテナ」ってのがあって、その実装を、vector,deque,listなどの中から
ポリシーで選べたら便利なんじゃないかと思うわけですが。
Effective STLには、たとえば「vectorをサポートしようとすると、push_frontとpop_frontを
使用できない」とか書いてあります。要するに、「全部に共通するメンバ関数がないから、無理」
ってなことに過ぎないわけでして。全部ラップして作り直せば問題解決なんでは、と思った
わけです。どうでしょう?
// ポリシークラスその1。vectorによる実装。
template<class T>
class ImplVector
{
public:
typedef std::vector<T> cont_t;
typedef cont_t::iterator Iter;
typedef cont_t::size_type SizeType;
private:
cont_t c_;
public:
void PushFront(T val){
c_.insert(c_.begin(),T);
}
void PushBack(T val){
c_.push_back(T);
}
void Erase(T val){
// eraseとremoveの慣用的用法ってやつ。
c_.erase(remove(c_.begin(),c_.end(),val),c_.end());
}
T& operator[](SizeType n){
return c_[n];
}
};
0682681
NGNGtemplate<class T>
class ImplList
{
public:
typedef std::list<T> cont_t;
typedef cont_t::iterator Iter;
typedef cont_t::size_type SizeType;
private:
cont_t c_;
public:
void PushFront(T val){
c_.push_front(T);
}
void PushBack(T val){
c_.push_back(T);
}
void Erase(T val){
c_.remove(T);
}
T& operator[](SizeType n){
Iter it = c_.begin();
for (int i=0;i<n;++i){
++it;
}
return *it;
}
}
// Generic Sequence Container
template
<
class T,
template <class> class ImplContainer = ImplVector
>
class GSC : public ImplContainer<T>
{
};
GSC<int> gsc;
gsc.PushBack(3);
gsc.PushFront(5);
gsc.Erase(3);
int a = gsc[0];
こんな感じで、効率の良し悪しは無視して、思いつく限りのメンバ関数を
用意しておけばいいんじゃないかなと。後で「vector実装でOKだと思ってたけど、
list実装の方がよかったな〜」ってときは、GSC<int>って定義をGSC<int,ImplList>に
変えるだけです。使ってる部分のコードは全く変更しなくていい、ってのが当然の目標。
……とかいって、どっかですでに開発されてましたー、じゃ虚しいんで、
存在を知ってる人がいたら、さっさとツッコミ入れてくださいね。
0683デフォルトの名無しさん
NGNG初期値を変更したくなったときに依存してるソース全部で
再婚パイルが必要なのって面倒い。
>>682
「vectorでOKだと思って operator[] を使って色々実装していたけど
やっぱりlistの方が良かったなー」なんてことは起こり得んと思うがどうか。
例えば std::queue のコンテナにはほとんどの実装だと list/deque は取れても
vectorは使えないけれど、それはvectorを使う意味が全くないからであって、
そこにあえてvectorを渡せるように汎用性を持たせる…みたいなことって
やってもしょうがないのでは。
0684デフォルトの名無しさん
NGNG> bool, int ,char , short, long , float, doubleと使えれば
> 充分じゃねーんすか?
いや、template に float や double (char もか?) の即値はつっこめないのではないかと。。。
0685681
NGNGいや、それは単にそういうありえなさそうな状況を挙げてるだけでは。(^^;
operator[]を使うって事は最初っからlistが考慮の外なのは明らかですから、
そういう状況を持ってきて否定されても。std::queueのほうも、目的が
はっきりしているなら、汎用シーケンスコンテナなんて必要ないのは
あたりまえです。
とりあえず、俺がこれを欲しいと思った動機を。vectorでもlistでもいいような、
曖昧な状況で『とりあえずvector』で開発をはじめたけど、あとで『げ、中間への
データ挿入が出てきた。やっぱlist』って切り替えたくなったんです。そのとき、
データ削除部分の形がvectorとlistでは全然違うやん、ってので参ったんです。
要するに、『どのシーケンスコンテナが最適なのか、不透明な状況』に対して
最適な回答をもたらすために、汎用シーケンスコンテナがあればいいなぁ、と。
どのコンテナが最適なのかわかんないうちから開発を始めてんじゃねーぞ、
って言われたら、「はい、ごめんなさい」と凹むしかないですが……。
0686デフォルトの名無しさん
NGNGいいんでないの?
いちおう、
どういうコンテナを使うべきかの分析無しで作りはじめてんじゃねーゾ。
0687デフォルトの名無しさん
NGNG0688668
NGNG私の場合は、テキストエディタを作るときに1行のテキストを
stringに入れて、listに入れて使いました。
stringはコピーにコストがかかるので、
vector::[] + insert よりは、
list::advance + insert の方がパフォーマンスがよかったです。
(advance 10万回で0.04秒程度)
しかしそれはコンテナの性質と設計上の要請を勘案すれば
事前に分かることで、わざわざポリシーにするほどのことではないと思うのですが。
0689デフォルトの名無しさん
NGNGもう常識中の常識。
それより、1行に持てるデータの構造をどう記述するかの方が問題。
0691デフォルトの名無しさん
NGNG0692デフォルトの名無しさん
NGNGlistとギャップバッファは用途違うと思うが?
それから、ギャップバッファも1行に保持するデータが長くなってくると
パフォーマンスががた落ちするよ、所詮2セグメントのデータだからね。
0693デフォルトの名無しさん
NGNGVC++6で、double即値、char即値ともつっこめますた。
0694648
NGNG死のう。
0695デフォルトの名無しさん
NGNGオブジェクト作るなって言いたいんじゃないのか?
そういう点でみれば>>692のは激しく的はずれ
0696デフォルトの名無しさん
NGNG0697デフォルトの名無しさん
NGNG最近のPCは速いし。
0698デフォルトの名無しさん
NGNG0699デフォルトの名無しさん
NGNGgapped buffer って、バッファの内容をカーソル位置で分割して管理する方法だよね。
それだと、コストはこうじゃないかな。
gapped buffer
一文字追加、削除 O(1)
指定行の移動 O(バッファの総文字数)
リスト
一文字追加、削除 O(一行の文字数)
指定行への移動 O(ファイルの行数)
gapped buffer は「普段よく使うのは一文字単位の追加・削除だから、こっちを
早くしたほうが快適だ」という信念に基づくデータ構造だと思うよ。ついでに、今
時の PC を前提とするなら、どっちでも早すぎて変わらん。
0700デフォルトの名無しさん
NGNGこれだと先頭から終端までジャンプするのに、バッファのコピーが発生するよね?
めちゃくちゃ遅くならない?
0701デフォルトの名無しさん
NGNG挿入・削除のタイミングでバッファ内の整理をすればよいので
全然そんなことない。
極端にでかいファイルもストレスなく開けるようにするのに便利。
0702デフォルトの名無しさん
NGNG何か書き換え始めたら行編集バッファにコピーしてきて編集し、
カーソルがその行から出たりするタイミングで書き戻してたっけ。
0703デフォルトの名無しさん
NGNGhead part cursor tail part
|-----------| + |------------|
こんな感じで持つ構造と考えて良いのでしょうか?
それとも、下の様にいくつかのフラグメントに分けて保存して、
編集時のコピー量を少なく納める構造なのでしょうか?
|-----| |-----| |----+-| |------|
日本語のサイトをいくつか検索しても、
どっちとも取れるようなどっちも違うような記述でよく分かりません
0704名無しさん
NGNG>>700
正直、editorならほとんど変りがない。今や一番重いのはGUIの描画。
0705デフォルトの名無しさん
NGNGカーソル位置とギャップ位置は関係ない
ギャップは普通エディットしている部分に作られる
0706デフォルトの名無しさん
NGNG0707デフォルトの名無しさん
NGNG0708デフォルトの名無しさん
NGNGhttp://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=utf8&oe=utf8&q=%E3%82%AE%E3%83%A3%E3%83%83%E3%83%97%E3%83%90%E3%83%83%E3%83%95%E3%82%A1
0709デフォルトの名無しさん
NGNG0710デフォルトの名無しさん
NGNGここにあるな
0711デフォルトの名無しさん
NGNGSTLPortのlower_boundに不具合があるんですけど、
どうにもならないですかね。
0712デフォルトの名無しさん
NGNGlower_boundにどんな不具合がありますか?
0713デフォルトの名無しさん
NGNGぉ!
Generic Programing and the STL見てみたら、
STLPortの動作のほうが正しいですね。
// MSDNには書いてない新たな条件が・・・
LokiPortのほうの使い方に問題があるみたいですね
0714デフォルトの名無しさん
NGNGちょっと前、Lokiの移植で話題になってたVCで
テンプレートの部分的な特殊化をエミュレーションしてる部分に
こんなコメントかいてあるんだけどあれのどこが not legal なの?
ーー以下引用ーーー
// the following VC6 specific implementation is *NOT* legal
// C++, but has the advantage that it works for incomplete
template<class T1>
struct is_same_part_1 {
template<class T2> struct part_2 { enum { value = false }; };
template<> struct part_2<T1> { enum { value = true }; };
};
ーー引用ココまでーー
他のコンパイラでは動かないのかな?
0715デフォルトの名無しさん
NGNGLokiを使えますか?
0716デフォルトの名無しさん
NGNG過去ログよめ
0717デフォルトの名無しさん
NGNG過去ログにはVC++.NETとあるだけなので、VisualStudioなのか
.NET Framework SDKだけでも大丈夫なのかわかりませんが。
0718デフォルトの名無しさん
NGNG一応、最適化のオプションが使えなくなってるだけで、
あとは普通にManagedも吐ければ、通常コンパイルもできる
まずは使ってから質問しろ。
lokiが使いたいだけならgccにしろ。
0719デフォルトの名無しさん
NGNG使うかどうかまだ決めてないんで。
情報どうも。
0720デフォルトの名無しさん
NGNGLokiPortを使えば?
http://www.geocities.com/rani_sharoni/LokiPort.html
0721デフォルトの名無しさん
NGNG0723デフォルトの名無しさん
NGNGg++だといけるんだけど。
0724デフォルトの名無しさん
NGNGそれがGeneric Programmingと何の以下略
0725デフォルトの名無しさん
NGNGコンパイラへのプログラミングにおいて
限られた道具が増えることは、かなり重要なことだと思うけど・・・
今のところ、どう使うか考えてるところではあるんだけどね:)
0726デフォルトの名無しさん
NGNG(まぁ C++ の template 自体、完全実装してる処理系はほとんどないから、
処理系依存に近いのが現状だけどさ)
0727デフォルトの名無しさん
NGNGhttp://www-cdserver.fnal.gov/cd_public/sag/J16/J16_files/slide0042.htm
• typedef templates:
template< class T >
typedef std::map< std::string, T > Dictionary;
Dictionary<double> d;
Dictionary<PhoneNumber> phonebook;
• typeof() compile-time operator:
template< class T >
void foo( T t ) {
typeof( f(t) ) y = f(t);
… ;
}
こりゃ凄いと思うがどうよ。
0728デフォルトの名無しさん
NGNG0729デフォルトの名無しさん
NGNG0730デフォルトの名無しさん
NGNG0731デフォルトの名無しさん
NGNG標準に含めて欲しいっていう提案はされてるみたい
0732デフォルトの名無しさん
NGNG0733標準化委員会
NGNG0734デフォルトの名無しさん
NGNGg++ってあれだけがんばってるのに、ユーザーは
相変わらずCでゴリゴリ書くのが好きな人ばっかりで、
なんか哀れだよね。
0735デフォルトの名無しさん
NGNG0736デフォルトの名無しさん
NGNG劇的にコーディングスタイルが変わりそう。
0737デフォルトの名無しさん
NGNGマクロプログラミングですか?
イヤだなぁ
0738デフォルトの名無しさん
NGNG#define foreach( itr, cont ) for( typeof( (cont).begin() ) itr = (cont).begin(); itr!=(cont).end(); ++itr )
0739デフォルトの名無しさん
NGNGtemplate<typename A,typename B>struct TSA{TSA(){cout<<"A"<<endl;}};
template<>struct TSA<T,int>{TSA<T,int>(){cout<<"B"<<endl;}};
template<>struct TSA<T,double>{TSA(){cout<<"C"<<endl;}};←これが警告になって、しかも無視されるのがわからない。なんで?
};
0740名無しさん@カラアゲうまうま
NGNG0741デフォルトの名無しさん
NGNGconst char* を受け取れるようにしとけば動作するけど、
template< unsigned N > f( const char (&x)[N] );
にバージョンを用意しとけば、文字列リテラルを受け取ったときに、
N で文字列長を受け取れる分、より効率的に処理できるようです。
ですが、↑みたいなテンプレートを使ってるのをほかで見たことがありません。
なにか問題があるからなのでしょうか?
それとも、見つけれて無いだけで、めずらしくもない方法なんでしょうか?
0742デフォルトの名無しさん
NGNGboos::type_traits::is_array
0743デフォルトの名無しさん
NGNG0745デフォルトの名無しさん
NGNG環境依存な部分も少なからずあるみたい。
ただ単にサイズを自動的に取得したいという目的ならば不要かと。
const char* との共存ができないようだし。(VC7)
普通にstring(literal, sizeof(literal))で問題無いかと。
0746デフォルトの名無しさん
NGNG0747デフォルトの名無しさん
NGNGこの業界辞める。もっとらくちんなの希望。
0748デフォルトの名無しさん
NGNGライブラリ作るのとそれ使うのとでは全然違うと思われ
0749デフォルトの名無しさん
NGNG激しく同意。
STLのように使うだけのライブラリとはちょっと違う。
プログラム設計において根本から変わってしまうような
ものだと思う。
というかそろそろ言語の機能をフル活用しなければならない
っていう呪縛から逃れたいところだね。C++使ってるひとには
自分も含めて、この傾向が強いから。
0750デフォルトの名無しさん
NGNG……と思ったが、そうすると他人のプログラムの保守ができんな。
0751デフォルトの名無しさん
NGNGtemplateなんて特にそうだと思うぞ。
俺は無いと困るみたいな状況に陥ったことがないので、
使ったことは無いが。w
■ このスレッドは過去ログ倉庫に格納されています