トップページ⇒tech
1001コメント388KB

【C++】template 統合スレ -- STL/Boost/Loki, etc.

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさんNGNG
C++ のジェネリックプログラミングの話をしましょう。
以下のスレッドを統合するスレです。

STLスレッド
Part1 http://pc.2ch.net/tech/kako/1004/10042/1004287394.html
Part2 http://pc3.2ch.net/test/read.cgi/tech/1026793823/

【C++】Boost使い集まれ!
http://pc3.2ch.net/test/read.cgi/tech/1033830935/

Generic Programming with C++ Template
http://pc.2ch.net/tech/kako/1008/10085/1008593126.html

関連スレ、その他リンクは >>2-5 あたりに。
0820デフォルトの名無しさんNGNG
>>818
多分
 template<typename T> void function( tmpl<T> t ) { ... }
という定義があれば tmpl<T> t; function(t); で見つけられるけど、
 template<typename T> void function( tmpl<T>::type t ) { ... }
では tmpl<T>::type t; function(t); では見つからないはず。

# スマートポインタを ptr<T>::shared とか ptr<T>::auto とか ptr<T>::locked
# とか書きたいけど書けねぇなぁ、という議論で見かけた気がする。

ので素直に、
1: set<list<N>::iterator> を(名前は適切なものをつければいいが) set_of_N_iter に置換
2: typedef set<list<N>::iterator,compare_dereferenced_address<list<N>::iterator> >
    set_of_N_iter;
しとけ。

あるいは、iteratorの比較関数をtemplateにしないで
bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
と一個一個書いていけばいいような気もするが。
0821812NGNG
>819
>set<list<N>::iterator>を使ってたところで全部同じ型を使うように汁。
ごもっともです。
それでうまくいかなかったのは、やはり元のコードがbuggyだったせいかと。

>820
>bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
>と一個一個書いていけばいいような気もするが。
これはどうも無理でした。

>では tmpl<T>::type t; function(t); では見つからないはず。
つまり、見つけられた(コンパイラ)の方がたまたまだったというわけでしょうか……

>ので素直に、 (中略) しとけ。
はい、そうしますわ。こつこつバグ治します。
0822デフォルトの名無しさんNGNG
どうでもいいけど、
ttp://groups.yahoo.com/group/boost/files/
とか見ていると、smart_ptr とか singleton とか
いい感じに Loki を取り込んでいってますな。
あと、次期 boost::lexical_cast 萌え

ところで、ここのコードって勝手に使っていいのかな?
0823デフォルトの名無しさんNGNG
>>821
素朴な疑問なんだけどさあ、iteratorってお互いの大小関係って
比較できたっけ?
==か!=でしか比較できなかったような気がするんだが。
0824デフォルトの名無しさんNGNG
それから、std::setの比較基準なんだけど、
1.std::set<Elem, Op>
2.std::set c(Op)
のどちらかでしか比較基準は指定できないよ。これを使わず
operator< を定義しても使ってはくれない。
0825デフォルトの名無しさんNGNG
>>823-824
> 素朴な疑問なんだけどさあ、iteratorってお互いの大小関係って
> 比較できたっけ?
だから812氏は苦労して { return &(*lhs) < &(*rhs); } なんて奇怪な
比較関数を作ってるんじゃねーの?

> のどちらかでしか比較基準は指定できないよ。これを使わず
> operator< を定義しても使ってはくれない。
set<T> とやったら比較ポリシーは std::less<T> になるから、
operator < が呼ばれる。つーか、キミ、勉強し直せ。
0826820NGNG
>>821
追実験。。
> >bool operator<( const list<N>::iterator& i, const list<N>::iterator& j ) { ... }
> >と一個一個書いていけばいいような気もするが。
Comeau のオンラインコンパイラで試してみたら、
 namespace std {
  bool operator<( const list<int>::iterator& i, const list<int>::iterator& j ) { ... }
 }
とstdの中に突っ込んで置いたら一応コンパイルは通ったぞい。
猛烈に行儀が悪いので、止めた方が無難だが。
0827デフォルトの名無しさんNGNG
それがランダムアクセスイテレータなら大小関係の比較できる。
0828812NGNG
>826
通りました! まさにピンポイントなアドバイス!
>猛烈に行儀が悪いので、止めた方が無難だが。
よそのコンパイラでお行儀悪くするためにはコツが必要なのですね。
ありがとうございます。

>827
なるほど。const list<N>::iteratorではなく、const vector<N>::iteratorの場合、
operator < を作る必要がなかったので不思議に思っていました。
勉強になりました。
0829デフォルトの名無しさんNGNG
boostやSTLportのtype_traitsをユーザー定義型で特殊化するサンプルってありますか?
0830デフォルトの名無しさんNGNG
次期vsはC++標準準拠度があがるみたいだけど
もうstlport使わなくてよくなるかな
0831デフォルトの名無しさんNGNG
もしかしたらVCもSTLport標準装備だったりして。
0832デフォルトの名無しさんNGNG
STLの実装がいくつもあってもあんまりいいことないよね
0833デフォルトの名無しさんNGNG
そろそろSTL開発会社も自然淘汰の時期だ。
0834デフォルトの名無しさんNGNG
managed C++ が多重継承できませんから。
stl なんか使いませんとも。
0835デフォルトの名無しさんNGNG
2つのvectorがあって、1方にだけ含まれる要素を
抜き出すにはどうすればよいですか?

片方に含まれる、両方に含まれる、どちらにも含まれる、で
処理を分けるようなこともしたいです。
0836デフォルトの名無しさんNGNG
>>835
ソート済みなら
std::set_union()
std::set_intersection()
std::set_defference()
が使えるかと。
0837デフォルトの名無しさんNGNG
>>835
片方にのみ含まれる - std::set_difference()
どちらにも含まれる - std::set_intersection()
両方の集合の和 - std::set_union()

但しこれらのアルゴリズムは必ず std::vectorを sort() してから
呼び出さなければならない。
0838デフォルトの名無しさんNGNG
ケコーン(w
0839836NGNG
親切度低いぶんだけ早かったな俺(w
0840仕様書無しさんNGNG
簡素な即レスと、丁寧な遅レスはどっちがより親切だろう?
0841デフォルトの名無しさんNGNG
>>840
両方あった方が良い(w
0842デフォルトの名無しさんNGNG
>>834
勘違いしている馬鹿発見。
0843デフォルトの名無しさんNGNG
低レベルな質問で恐縮ですが
VC7にSTLportを導入した、つもりなんですが
どうも上手くいっていないみたいです。

ちゃんとSTLportが使われているかチェックする方法はないですか?

インクルードディレクトリを切り替えてlistの性能比較とかしても差がないし、
iostreamもSTLport版を使うようにし他場合、
#define _STLP_USE_DYNAMIC_LIB してできた実行ファイルを
Dependency Walkerで調べたらstlport_vc745.dllが表示されると
思っていたんですが、表示されませんでした。思い違いでしょうか?
インストールが上手くいっていないだけですか?
0844デフォルトの名無しさんNGNG
>>843
std の変わりに _STL ネームスペースを使って正常にコンパイル
できるかどうかチェックする。
0845843NGNG
>>844
コンパイルできませんでした(泣
導入からやり直します。ありがとうございました。
0846デフォルトの名無しさんNGNG
>>845
SGI系のアダプタである _STL::compose1 とか _STL::compose2 が
コンパイルできるか確かめてみる方法もあるよ。
0847デフォルトの名無しさんNGNG
std::vector x(10);
for(int i=0;i<10;++i) cin >> x[i];

を for で回さないでなんか algorithm 使って出来ないですかね?

std::vector x(10);
std::transform(x.begin(), x.end(), x.begin(), bind1st(std::mem_fun(&std::istream::operator>>), &std::cin));

で逝けるかなぁと思ったんですけど、
no matching function for call to `mem_fun(<unknown type>)'
と gcc-3.2.1 に言われてしまって…
まぁ完全に趣味なんで別に for で回せばいいんですけどね。
0848デフォルトの名無しさんNGNG
>>847
#include <iterator>
std::copy_n( std::istream_iterator<T>(cin), x.size(), x.begin() );
0849848NGNG
って、copy_n ってもしかしたらSGI拡張だったかも…。
0850デフォルトの名無しさんNGNG
>>848
やってみたけど11個数字を入れないと終了しないよ。
STLport。
0851デフォルトの名無しさんNGNG
>>847
多分それがだめなのは、operator>>の戻り値型がstd::istreamだから
だろう。
0852デフォルトの名無しさんNGNG
>>847
ファンクタを作ったらだめかい?

template <typename T>
struct input {
T operator()(T& t) {
std::cin >> t;
}
};

int main()
{
std::vector<int> x(10);
std::transform(x.begin(), x.end(), x.begin(), input<int>());
std::copy(x.begin(), x.end(), std::ostream_iterator<int>(std::cout, " "));
}
0853848NGNG
>>850
おー、ほんとだ。istream_iterator って operator* じゃなくて
コンストラクタと operator++ のタイミングで読まれるのか。使いにくいな。
0854デフォルトの名無しさんNGNG
スマソちょっと修正。

template <typename T>
struct Input {
T operator()(T& t) {
std::cin >> t;
return t;
}
};
0855デフォルトの名無しさんNGNG
入力にtransformはねぇだろ。

template< typename T >
struct input_from_cin
{
 T operator () ()
 {
  T temp;
  cin >> temp;
  return temp;
 }
};
int main()
{
 vector< int > v;
 generate_n( back_inserter( v ) , 10 , input_from_cin< int >() );

 copy( v.begin() , v.end()
    , ostream_iterator< int >( cout , " " ) );
}
0856847NGNG
なるほど、皆さんありがとです。

>>848
copy_n は知らなんだです。gccのSTLにはあるみたいなんで良さそうですね。
でも確かに >>853 のような事に

>>851
それだと <unknown type> なんですか?そもそもこのエラーメッセージが良く分からんっす。
ちゃんと iostream は include してるから未知って事は無いと思うんですが…

>>852
まぁもちろんファンクタ作ればいいんですが、なんとなく一行野郎で行きたかったんで…

>>855
そうなんですが、一行野郎を目指したら個数を指定する為に無理矢理行き着いたのが
transform でして…可読性はゼロですけどね(w
0857デフォルトの名無しさんNGNG
for_each( v.begin(), v.end(), cin >> boost::lambda::_1 );
とか言ってみる。
0858デフォルトの名無しさんNGNG
>>857
(・∀・)ソレダ!!
0859847NGNG
>>857
基本を忘れてますた…(w
# 基本か?
0860デフォルトの名無しさんNGNG
lambdaはなぁ・・・。
0861デフォルトの名無しさんNGNG
どうしてもランバダと読んでしまう。
0862デフォルトの名無しさんNGNG
ランバダ算法騎士団
0863tanteiNGNG
★あなたのお悩み解決致します!!
●浮気素行調査
彼氏、彼女、妻、夫の浮気を調査致します!!
●盗聴器盗撮機発見
あなたの部屋に誰かが仕掛けているかも!!
●行方調査
行方不明になっている家族の消息を調査致します!!
●電話番号から住所割り出し
一般電話、携帯から住所を割り出し致します!!
●ストーカー対策
社会問題ともなっているストーカーを撃退致します!!
その他人生相談からどんなお悩みでも解決いたします!!
 直通  090−8505−3086
URL  http://www.h5.dion.ne.jp/~grobal/
メール  [email protected]
   グローバル探偵事務局 

0864デフォルトの名無しさんNGNG
★あなたのお悩み解決致します!!
●浮気素行調査
VB、JAVA、C#、COBOLの浮気を調査致します!!
●トロイ、ウィルス発見
あなたのプログラムに誰かが仕掛けているかも!!
●行方調査
行方不明になっている変数の消息を調査致します!!
●関数名からアドレス割り出し
.dll、.objからアドレスを割り出し致します!!
●バグ対策
社会問題ともなっているバグを撃退致します!!
その他設計相談からどんなお悩みでも解決いたします!!
 直通  http://pc2.2ch.net/tech/
URL  http://www.2ch.net/
メール  [email protected]
   2ちゃんねるプログラム板 

0865STL初心者NGNG
vector<bool> は使うな という話を小耳にはさんだのですが、ほんとうでしょうか?
0866デフォルトの名無しさんNGNG
boolのvectorとして使うつもりならば本当です
0867デフォルトの名無しさんNGNG
>>865
std::vector<bool>は過去の実装の遺物です。
固定でもよければstd::bitset、可変長が必要ならboost::dynamic_bitset
を使いましょう。
0868デフォルトの名無しさんNGNG
別に使ってもいいと思うよ。
ただし普通のvectorだと思って使うと細かいところで問題が起こる。
あと1要素が1bitで実装されてる保証はない。
0869デフォルトの名無しさんNGNG
>>865
bool型へのポインタが取得できません。
0870STL初心者NGNG
>>867
固定長じゃないんですよー
>可変長が必要ならboost::dynamic_bitset
情報どもです。あとで調べます。
>>868
>ただし普通のvectorだと思って使うと細かいところで問題が起こる。
「細かいところ」って具体的にどんなことなんでしょう?
ビットにパックされているために bool *p = &vecBool[x]; とかができないとか?
push_back(), insert(), erase() と 値の参照、設定さえできればよいのだが
このあたりのことを詳しく説明したドキュメントってどこかにないのかなぁ
それともSTLのソースを読むしかないの?
0871STL初心者NGNG
VC++6.0 を使っているのですが、ソースを読んだり、デバッガでトレースしてみたところ
vector<bool> は1要素を1ビットで表現するという特別な処理をしているようには見えませんでした。
ということは VC++6.0 であれば vector<bool> を使っても問題ないと理解してよろしいのでしょうか?
0872デフォルトの名無しさんNGNG
>>871
使うコンパイラに関係なくstd::vector<bool>を使っても問題ないが、
メンバ関数が返す値はboolへのリファレンスでなくてプロキシである
ことを知っておく必要がある。
>>870さんも言っているように、
bool* p = &vecBool[x]; のようなコードがコンパイルできない。
0873デフォルトの名無しさんNGNG
>>870
> ビットにパックされているために bool *p = &vecBool[x]; とかができないとか?
当たり。できません。
んでもって、これができないモノは正確には「コンテナではない」んだそうです。
よって「vector<bool>はSTLコンテナではない」が成り立つとかなんとか。

なんとなく心配なら、deque<bool>を代用品に選んどくのもいいかも。
0874デフォルトの名無しさんNGNG
>>871
例えばVC++6 ProのSP5なら、<vector>の245行目以下で
boolをunsigned intにパックしてるが。
0875STL初心者NGNG
>>874
あれっ、ほんとだ。
でも vector<bool> vb; と宣言し vb.push_back(true); を実行しても
class vector<_Bool, _Bool_allocator> が利用されていないように
見えるが・・・
0876STL初心者NGNG
それに VC++6.0 で
vector<bool> vb;
vb.push_back(true);
bool *pb = &vb[0];
をコンパイル実行してみると、問題ないようだぜ。
パックするには何かおまじないがいるのかな?
0877デフォルトの名無しさんNGNG
std::vector<bool>で
std::vector<bool, std::allocator<bool> >か、
bool専用のアロケータが使われるかは処理系依存で
さらにbool専用のアロケータの名前も規定されてない
0878デフォルトの名無しさんNGNG
VC.netで、boostのコンパイルがうまくできません。
bjamとかって標準のインストールパスにしか対応していないのですか?
0879デフォルトの名無しさんNGNG
最近STL使い始めた初心者です。
グローバルでSTL宣言すると12バイトのメモリリークが起きるようなんですが、
これの解消法ってどうすればいいんですか?
0880デフォルトの名無しさんNGNG
>>879
よーわからんけど、「12バイトのメモリリーク」 はどうやって確かめたの?
0881デフォルトの名無しさんNGNG
template <class charT>
const charT *mes()
{
return "message";
}

質問です
mes<char>(); //はOK
mes<wchar_t>(); //だめ、理由はわかってます。でもどうしたらいいのでしょうか
0882デフォルトの名無しさんNGNG
return TEXT("message"); // ←こうかもしれない。
0883デフォルトの名無しさんNGNG
>>881
template <>
const wchart_t *mes()
{
return L"message";
}
0884デフォルトの名無しさんNGNG
>>883
ああ、そりゃそうですね・・・
ども
0885879NGNG
>>880
あ、すみません、説明不足でした。

list<int> hoge;
という風にグローバルで宣言して、そのまま終了すると
12バイト漏れる、ということで。

メモリリークを調べるのには
_CrtDumpMemoryLeaks()
を使いました。
0886デフォルトの名無しさんNGNG
グローバルに静的に確保されたオブジェクトにリークもクソもないと思うが。
0887デフォルトの名無しさんNGNG
グローバルで宣言したクラスの
コンストラクタとデストラクタが呼び出されるタイミングと
_CrtDumpMemoryLeaksが呼び出されるタイミングを考えてみろ
0888デフォルトの名無しさんNGNG
VC6だとlocaleでリーク起こすけど
using namespace std;
try{
locale::global(locale("2ch"));
} catch(exception &e) {}
これでリーク起こす。
0889デフォルトの名無しさんNGNG
>>888
VC6はC Runtimeのソース付いてるから直せるぞ
0890879NGNG
>>887
あー・・・。
気付きませんでした。どうもです。
0891デフォルトの名無しさんNGNG
VC6の出力が \ になるのですが、なぜに?

#include<sstream>
#include<string>
#include<iostream>
#include<vector>
using namespace std;

int main()
{
basic_stringstream<wchar_t> S;

const char c[]="圭";
size_t size = mbstowcs(NULL,c,0);
vector<wchar_t> tmp(size+1);
wstring data;
mbstowcs(const_cast<wchar_t*>( &tmp[0] ),c,size);
*(static_cast<volatile wchar_t*>( &tmp[0] )+size) = L'\0';
S << &tmp[0];
S >> data;
wcout << data;// VC6だと\, VC.NETだと圭
}
0892デフォルトの名無しさんNGNG
まず、setlocaleしる。

> mbstowcs(const_cast<wchar_t*>( &tmp[0] ),c,size);
> *(static_cast<volatile wchar_t*>( &tmp[0] )+size) = L'\0';
ここのキャストは要らないと思うんだけど。
 mbstowcs(&tmp[0],c,size);
 tmp.back() = L'\0';
これでいいはず。

んで、試してみたけど。
 wcout << &tmp[0] << endl;// 「圭」
 wcout << S.str() << endl;// 「圭」
 wcout << data << endl;// なにもでない

> S >> data
こいつがうまくいかないみたい。
原因は追いきれなかった。
0893デフォルトの名無しさんNGNG
VC6.0です(STL?)。

Redo/Undoの機能をつけるために
ポインタをポインタの配列で管理しようとしているのですが

配列のサイズを決めて新しい要素を入れると
古いものから順に消していってくれるような都合のいい
クラステンプレートってないですか?
0894デフォルトの名無しさんNGNG
>>892

>setlocale(LC_ALL,"Japanese");を忘れてました。

ライブラリ側の問題ぽいので
S.str()で回避して使っていこうと思います。

ありがとうございました。
0895デフォルトの名無しさんNGNG
>>893
std::queueのラッパーでいいんじゃねーの。
0896デフォルトの名無しさんNGNG
キュー、っつーかリングバッファだな。
リングバッファを実現するコンテナアダプタはSTLの解説で幾つか見たことあるが、
公開されてるものはない気がするから自分で作ったほうがはやそう。
0897893NGNG
>>895, 896
どっかから参考になりそうなものを探して自作することにします。
ありがとうございました。
0898デフォルトの名無しさんNGNG
FIFOバッファだからdeque使えばいいだけの話じゃないの?
0899 NGNG
stlport_vc6.dll を stlport.dll にリネームして使いたいと思います。
方法がわかる方はいらっしゃいませんか?
いらっしゃいましたら、方法を教えてください。

まさか stlport_vc6.lib をバイナリ・エディット?
0900デフォルトの名無しさんNGNG
G++でwcoutを使うにはどうすればよいのでしょうか?
0901デフォルトの名無しさんNGNG
std::vector<std::string> a;
ってやっちゃだめなの?
0902デフォルトの名無しさんNGNG
>>901
当然良し。
0903デフォルトの名無しさんNGNG
vector<bool>を使ったらだめな理由がわかりません。
つーか便利だよ
vector<char>だと8倍メモリくうし

bool *p=&vec[0];
これができないとなんでだめなんだよー
0904デフォルトの名無しさんNGNG
http://www.agemasukudasai.com/bloom/
0905デフォルトの名無しさんNGNG
>>902
vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
なんかあやしいきもするんですが・・・
0906デフォルトの名無しさんNGNG
>vcでレベル4でコンパイルするとめちゃめちゃヲーニングでるけど
VC6発見

#pragma warning (disable : 4786)
ソースの先頭に置いときなさい
0907デフォルトの名無しさんNGNG
>>906
はーい
0908デフォルトの名無しさんNGNG
>>885
ちょいと遅レスだがたしかSTLは効率のために内部にちょびっと
つねにメモリもってるらしいよ。どっかの過去ログにあるはず。
で、どっかで何かをdefineすればなくなるがパフォーマンス
悪くなる。(ってことなのかな?的外れだったらスマソ)
0909デフォルトの名無しさんNGNG
>>908
そういうのはメモリリークとは言わないけどね。
0910デフォルトの名無しさんNGNG
>>908
メモリプールといいます。そういうのは。
0911デフォルトの名無しさんNGNG
コンテナとかはstlport使ってるんですが、
stlportのiostreamを使う利点はあるのですか?
static-linkだと容量でかくなるし
もしたいした違いがないならコンパイルせずに
標準のiostream使おうと思うので
教えてください
0912デフォルトの名無しさんNGNG
STLportのCVSにWinCVS(or TortoiseCVS)でアクセスできませんか?
0913912NGNG
もちろん、読み取りだけで十分です。
0914デフォルトの名無しさんNGNG
>>900
glibc のバージョンが古いと思われ。
glibc-2.2(だったかな?)以降が入ってる環境を使うべし。
0915デフォルトの名無しさんNGNG
 set<string> coll;
という変数宣言がされている状況で、
 for_each(istream_iterator<string>(cin), istream_iterator<string>(),
      coll.insert);
としたいんだけど、gcc-2.95.3 では
no matching function for call to `for_each (istream_iterator<string>, istream_iterator<string>, {unknown type})'
とエラーになってしまう…
(本当はもっとエラーメッセージが長いけど、適宜省略)

プロ言C++第3版の13.2.3を見ると「テンプレート引数としては…メンバに対す
る多重定義されていないポインタなどが使える」とあって、これからすると、
このset<string>::insertみたいな多重定義されているメンバ関数はテンプレート
引数としては渡せないような気もするんだけど、これって本当?
0916915NGNG
やりたいことは、下記のような関数オブジェクトInserterを作って、
 template<class Collection>class Inserter {
  private:
     Collection *container;
  public:
     Inserter(Collection &c) { container = &c; }

     void operator()(const typename Collection::value_type &v)
     {
         (*container).insert(v);
     }
 };
coll.insert の代わりに Inserter< set<string> >(coll) と書けば
できたけど、なんか納得いかないというか、イマイチGenericじゃない
気がしてる。実際、for_eachを手で展開して
 istream_iterator<string> in(cin);
 while (in != istream_iterator<string>())
     coll.insert(*in++);
とすれば動くだけに、なんかクヤしい。
なんか良い手ないかしら?
0917デフォルトの名無しさんNGNG
std::insert_iterator, std::inserterというのがあるわけだが。
0918デフォルトの名無しさんNGNG
#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
std::set<std::string> sset;
std::copy(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::inserter(sset,sset.begin()));

std::copy(sset.begin(),sset.end(),std::ostream_iterator<std::string>(std::cout,"\n"));

return 0;
}
0919デフォルトの名無しさんNGNG
>>916

std::set<std::string> coll;
std::copy(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::insert_iterator<std::set<std::string> >(coll, coll.begin()));

std::setに関するstd::insert_iterator()の定義はちょっと面白いようになっている。
c.insert(p, t) を呼び出すわけだが、std::setではinsertのメンバ関数は探索位置を
指定する必要はない。だが互換性のためにヒントとしてパラメータを持っている。
そのためstd::insert_iterator()が使えるのである。
レス数が900を超えています。1000を超えると表示できなくなるよ。