【C++】STL(Standard Template Library)相談室 6
とりあえず貼っとく。
http://pc8.2ch.net/test/read.cgi/tech/1104898734/562 562 名前:デフォルトの名無しさん[sage] 投稿日:2005/05/05(木) 02:58:39
"STL"なんて呼称の範囲は、C++の標準ライブラリに
取り込まれてしまった今となっては明確に区切れる物では無い。
HP STL や SGI STL のことを指して言ってるのかもしれないが、
今使われてるのはそれらをベースにしたC++標準ライブラリだ。
範囲が明確に決まってるかのように、含まれるだの含まれないだの言うのは時代遅れだぞ。
このスレが不要である事に疑いの余地は無い。
3 :
デフォルトの名無しさん :2006/10/14(土) 19:28:17
質問。 連想コンテナへのinsert(i, j) (iとjは入力反復子)って、 例外安全性は強い保証?それとも基本? 規格を眺めたが言及が見つからず…
STLのスタックはC#のスタックに比べて10倍遅い。 C++はメモリのアロケートが貧弱な気がする。
>7 規格とDR読み通したけれどこれは単に抜けてるだけのような
規格で例外安全性に関する規定ってあったっけ? 無いと困るような気はするんだが、ちょっと見当たらない。
>>11 あちこちに散りばめられている。(個々の関数の解説にあったり、先頭で一斉に指定されていたり)
>>8 本当にありケーとが駄目というのが原因なら、アロケータを差し替えてみるとどうだろう?
13 :
8 :2006/10/16(月) 18:48:40
>>9 普通にforループでpushしていくだけのもの。
>>12 STLportに変えてみたら同じぐらいの速さが出た。
VC8標準のやつが遅かっただけみたい。
14 :
8 :2006/10/16(月) 18:57:27
stackのpushよりもvectorのpush_backの方が速いとは……
stack はキューだかリストだか使っているからだろう。
速度比較してソース貼らずに結果だけを主張するのはおかしいだろ。
的外れ
>>19 >STLportに変えてみたら同じぐらいの速さが出た。
>VC8標準のやつが遅かっただけみたい。
って、8にとっての結論は出てるみたいだからそれでいいじゃん
お前がどう評価するかは、それぐらい自分でベンチとれよ
22 :
17 :2006/10/16(月) 20:49:07
別にベンチマークがとりたいんじゃなくて、どんなコードで 比較したのかが知りたかったんだ。自分で新しく比較コード書く気は無いな。 本人が拒否するならわかるんだが、なんで他人が文句言ってくるんだ?
確かに C# より遅いってのは屈辱的だな
Dimkumwareは糞遅いからな。
テンプレか思った
>>22 お馬鹿さんの不思議ルールを理解しようとしても無駄。
int main(int argc, char * argv[]) { boost::numeric::ublas::vector<float > vec(2); vec(0)=1.0;vec(1)=2.0; boost::function1< float,boost::numeric::ublas::vector<float> > norm_2Functor = &boost::numeric::ublas::norm_2<boost::numeric::ublas::vector<float> >; float out= norm_2Functor(vec) ; } 想定外のメモリーを参照しました で落ちる。何が悪いのだろう。
30 :
デフォルトの名無しさん :2006/10/18(水) 01:46:19
listについて質問です。 erase()で、イテレータで指定した位置の要素を消せますが、 消した後このイテレータは有効なのでしょうか?無効なのでしょうか?
つ i++
33 :
デフォルトの名無しさん :2006/10/18(水) 02:38:20
ということは、erase(it)のあと、it++などとやったらいけないのですか?
>>33 うん。ダメ。だから erase(it++) という話で
>>31 に行く。
エスパー過ぎたなww
これってシュール? vector<mydata*> * vec; vec = new vector<mydata*>(); delete vec;
ベンチしたらVC標準の方がSTLportより速かったぞ。
>>34 vectorの場合を考えて普通eraseの戻り値使わない?
便乗して質問なんですが、 std::vectorのeraseしたときの要素削除で 実際にヒープ開放しないように指定することは不可能? 頻繁に数が変動する場合、自分で制御した方がいいんでしょうか
vectorは確保した領域をいちいち開放しないんじゃないの? resize()でサイズを小さくしても領域は開放されないとか書かれていたけど。
struct Data { int id; (他にもいろいろ) }; std::vector<Data*> dataSet; にid順にpush_backで詰め込んであります。 bool Compare( const Data* p, const int v) { return (p->id < v); } int id = 探すid番号; std::vector<Data*>::iterator it = std::lower_bound( dataSet.begin(), dataSet.end(), index, Compare); で、find_ifより高速に検索ができるかと思ったのですが、 vc8では lower_bound内で Compare( int, Data*)が必要らしく コンパイルが通りません。Compare( int, Data*)を定義すると どちらのCompareなのかあいまいだと言われてます。 解決方法を教えてください。
45 :
デフォルトの名無しさん :2006/10/19(木) 00:44:38
>>44 struct compare{
static bool operator()(const Data* p,int v){return p->id<v;}
static bool operator()(int v,const Data* p){return v<p->id;}
};
を定義してCompareの代わりにcompare()を渡せばいい。
46 :
44 :2006/10/19(木) 01:51:22
>>45 コンパイルを通すには、 Data<int, int<Dataだけでなく、Data<Dataも必要でした。
ありがとうございました。
operator()を3つ定義するならoperator<を3つ定義して
lower_bound(start,end, 値);でも結局、手間は同じなのかも?
以下のコードでコメントアウトしてあるdelete dの部分なんですが コメントにすればメモリリーク コメントにしなければvectorにデータが入らない こういった場合どうすればよいのでしょうか #include <iostream> #include <vector> using namespace std; struct data{int i;}; struct my{ vector<data*> dat; void add(){data* d = new data(); d->i=10; dat.push_back(d); //delete d; //コメント外すとvectorにデータが入らない } void p(){for(int i=0;i<dat.size();++i){cout << dat[i]->i << endl;}} }; int main(){ my m; m.add(); m.p(); return 0; }
>>47 myのデストラクタでdatの要素全てdeleteするか、boost::ptr_vectorを使う。
あ、あとvectorの要素をdataそのものにする。
data の要素が int 程度なら vector<int> を使う
51 :
47 :2006/10/20(金) 21:33:05
>>48 ,49
回答ありがとうございます
>myのデストラクタでdatの要素全てdelete
あ!つい、自動的にやってくれるもんだと思ってた
vectorはポインタの中身の削除には感知しないんでしたね
要素をdataにするほうは派生クラスのポインタも入れたりするので
今回は
>>48 のほうで頑張ってみます
行き詰ってましたがこれで何とか先に進めそうです
助かりました!
52 :
47 :2006/10/20(金) 21:36:36
>>50 補足どうもです
小さいデータでは直接intのほうがよさそうですね
47のコードは状況を再現する最小コードで
実際はもうちょっと複雑なデータ構造になっています
本当にint型のメンバ1つでも、intそのままよりtypedefの方が良いと思う。
>>53 つまりこうか?
template <typename T> struct data{ typedef T value_type; T i; };
と定義して、
typedef int HogeType;
とtypedefして、
my<HogeType> m;
と使う、と。
>>54 typedef struct
{ int i; }data;
dataに別の変数を付け足したくなった時に便利。ってことじゃないか
いや、単にtypedef int data;のつもりだったんだが。
boost関係もここ?
vectorの削除について質問です remove(v.begin(),v.end(),1)みたいなのだと要素数は減らず eraseと組み合わせたら要素数も減る v.clear()だと要素数は0になるんですよね それでは要素数はそのままで、 vectorの中身を全部削除(適切な言葉がわからない) するにはどうしたらいいのでしょうか remove(v.begin(),v.end(),?)
61 :
59 :2006/10/22(日) 18:49:20
>>60 vectorをキャッシュみたいに利用できないかと考えたんです
v.begin()〜v.end()の内容をあるときに全部他に書き出して
v.begin()〜v.end()を初期化して再利用
この時、clear()を呼んで初期化すると
確保したメモリも削除されるので勿体ないかなと
>>61 何が勿体ないのかわからんが、 vector には reserve() があるんで、
clear() でメモリを解放する実装は考えられない。
63 :
59 :2006/10/22(日) 18:59:16
>>62 すみません、どうやら勘違いしてたみたいです^^;
clear()で行こうと思います、失礼しました
メモリ解放するときはreserve(0)? 明示的破棄は不可能なんでしょうか?
>64 std::vector< int >().swap(v);
>>65 見た感じヤバイ印象を受けるのですが
スタンダードなやり方なんですか?
>66 >見た感じヤバイ印象を受けるのですが あなたは仕様やドキュメントではなくて見た感じの印象でコードの可否を決めるの? >スタンダードなやり方なんですか? 何をもってスタンダードとするかは分からないけれど swapイディオムというよく使われる方法の延長
>>66 vector* でも持って new/delete すれば確実だろう。
>>67 初めて見るコードでイディオムっていうのを知らなくて。
無知ですみません。勉強になりました。
70 :
デフォルトの名無しさん :2006/10/23(月) 00:01:07
vectorが合ったら配列っていらないような気がするけど、必要なの?
>>70 C との互換性のためには必要。文字列リテラルも配列型だしね。
動的確保を必要としないという点も見逃せない。
固定長配列の需要もなくなりはしないよ。
boost::array, std::tr1::array でほとんど置き換えることは可能なんだろうけど、 やっぱり不要ってことにはならないだろうねぇ。
>73 それらの実装に固定長配列が要るだろ。 まあそれを言ったらstd::vectorの実装にnew []が必要とかそういう次元の話になってしまうが。
でも、配列を使う機会は減りそうだな。
配列がなかったらvectorもなくなるじゃん
mallocとポインタで何とか
78 :
デフォルトの名無しさん :2006/10/23(月) 21:43:06
std::vectorに、at()という関数が見つかりません。 VisualC++だとあるのですが、gccにはありませんでした。 これは標準の関数ではないのでしょうか?
join は難しいんじゃない?
#include <vector> #include <numeric> #include <string> std::vector<std::string> v; v.push_back("test"); v.push_back("orange"); v.push_back("apple"); std::string s; s = std::accumulate(v.begin(), v.end(), std::string()); printf("[%s]\n", s.c_str()); これでいいのかしら?
あ、joinは単に結合するだけじゃなくてセパレータがいるのか… transformもつけると意味が変わりそうな気もするし
chopもpythonのs[0:-1]がOKなら、C++でも、なにか書き方がありそうな気がする。
84 :
デフォルトの名無しさん :2006/10/23(月) 22:32:54
vectorで2次元配列を作るとして、 イテレータで[]演算子を使ってアクセスすることはできますか? at()だと、下記の書き方でうまくいくのですが…範囲チェックの分のコストが惜しいので できるだけ[]演算子でアクセスしたいのです。 vector<vector<int> > v; for( vector<vector<int> >::iterator i=v.begin(); i != v.end(); i++ ) { i->at( 0 ) = 1; }
これならいける? #include <boost/lambda/lambda.hpp> namespace bll = boost::lambda; std::string s = std::accumulate( v.begin(), v.end(), std::string(), _1 + bll::make_const(", ") + _2 );
87 :
デフォルトの名無しさん :2006/10/23(月) 23:29:50
STL使うと容量が増えている気がするんですが、気のせいでしょうか?
>>78 標準。
GCCにないわけがない。なにか古い版か?
STLをjavadoc形式で表したいんですけど、参考になるサイトとかないですか?
>>93 STLをjavadoc形式で表すってどういうことか説明してみそ
エスパー的にDoxygenはどうだ?
doxygenを使おうとは思ってたのでインストールはしています…あと一応eclipseも とりあえずSTLのどれからでもいいんでドキュメント化したかったんですけど STLのソースに書き込むの難しそうだったんで そういうの補足してくれてるサイトとかあったら教えてほしかったんですけど…
STLくらいメジャーなものだったら本やネットで公開されてる マニュアルのほうが完成度が高い
g++3.4.5 stdc++ のrandom_shuffle() の実装なんですけど > for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) > std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); なんかビミョー?
template<typename MANY_FLOAT > class MyContainer { MANY_FLOAT &data_; MyContainer(TWO_FLOAT &_data_ ):(data_(_data_)) }; float _data_[100]; MyContainer myContainer(_data_); MANY_FLOAT に float*nの大きさを指定してn個飛ばしでdataにアクセスしたい。 MANY_FLOATにはどんなクラスを指定すればいいのでしょうか
>>100 typename 引数で「大きさを指定」するのか?
「n個飛ばし」って何だ?
TWO_FLOAT って何?
MyContainer のコンストラクタ、コンパイルできないだろ。
MyContainer はテンプレートなのに、 myContainer の
宣言ではテンプレート引数が指定されていない。
質問を整理して、コンパイルできるコード貼ってくれ。
_firstと_lastが同じでも大丈夫なんだろうか
rand()%Xがイマイチ
106 :
100 :2006/10/25(水) 16:45:39
自己解決 tinyvecorってこういうとき使うものなのね
vectorで型の違う2次元配列をtransform()を使って変換したいんですが、 どういう風に書けばいいでしょうか?
>>104 > コンテナが空の場合のチェックは引用してないとこでやってるの?
たぶんそう。漏れの手元にあるのはgcc-3.4.6付属版だけど、全文はこう。
gcc-4.1.1も同じだった。
template<typename _RandomAccessIterator>
inline void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
}
やっぱ rand() % X がなー。質にも値の範囲にも問題あるんじゃ?
気になるなら random_shuffle(first, last, op) 使えって感じか。
あと、inlineついてるのね。
>>108 どういう風に書いてうまくいかなかったのか?
111 :
108 :2006/10/26(木) 00:51:11
すみません、自己解決しました。 vector<vector<T> > v1( 10, 10 ); vector<vector<X> > v2( 10, 10 ); vector<vector<T> >::iterator i=v1.begin(); vector<vector<X> >::iterator j=v2.begin(); for( ; i != v1.end(); i++ ) { transform( i->begin(), i->end(), j->begin(), convert<T, X>() ); } の記述で通りました
VineLinux3.2で、libstdc++3.3.6だとワイド文字周りが正常でなかっ た為synapticからSTLPort(4.6.2)をインストールしました。 ライブラリが/usr/libに、ヘッダーが/usr/include/stlportにインス トールされました。 試しに #include <iostream> #include <locale> using namespace std; int main() { locale::global(locale("japanese")); } を g++ main.cpp -I/usr/include/stlport -lstlport_gcc でコンパイルして実行したところ、何故かアボート。 何か間違ってますか?
スレ違いのような気がしなくもないけれど。 単にstd::locale::global(std::locale(""));だとどう?
114 :
デフォルトの名無しさん :2006/11/01(水) 01:11:12
locale("C");ならアボートしませんけど、locale("japanese") でダメっつーのは、いかんのでは?
>>112 locale のコンストラクタが例外を投げることになってるんで、こうしてみると
#include <iostream>
#include <locale>
#include <exception>
int main()
{
using namespace std;
try { locale::global(locale("japanese")); return EXIT_SUCCESS; }
catch (exception const& e) { cerr << e.what() << endl; return EXIT_FAILURE; }
}
cygwin g++ 3.4.4 だと↓のようになった。
locale::facet::_S_create_c_locale name not valid
>>114 locale文字列は"C"と""以外処理系定義のはず。
>>109 Working Draftにそもそもこう書いてあるから、別にgccのせいじゃないだろ。
25.2.11 Random shuffle [lib.alg.random.shuffle]
4 Remarks: The underlying source of random numbers for the first form of the function is implementation-defined.
An implementation may use the rand function from the standard C library.
実装依存なんだから結局
>気になるなら random_shuffle(first, last, op) 使えって感じか。
だな
working draftで語るのはどうかな… ISO/IEC14882 みて語ろうぜ。
>>117 >別にgccのせいじゃないだろ。
単に出典を示しただけだろ。着眼点がずれてるよ。
俺が使ってるSTLportも似たようなもんだった。
そもそもrand()の性能がよければ問題無いつー話では? rand()%X より rand()*X/RAND_MAXのほうがいいとかはあるかも知らんが.
121 :
120 :2006/11/01(水) 14:19:28
あ、計算違ってるかも RAND_MAX じゃなくて (RAND_MAX+1)?
>>117 「std::rand使うかも」まで書いてあるのね。参考になった、さんくす。
>>119 STLportの4.6.2と5.0RC2を見てみた。どっちのバージョンでもまったく同じ。
if (__first == __last) return;
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
iter_swap(__i, __first + __random_number((__i - __first) + 1));
__random_number は "rand() % X" と "lrand48() % X" のどちらか。マクロ切替。
>>120 確かに。実装で自由に定義していいんだから、
変に凝らずrandまかせで済ませるってことか。
>>121 RAND_MAX+1はinteger overflowになるかもよ。(実装定義だけど)
ISよりWCの方を参考にするのかw
124 :
123 :2006/11/01(水) 16:45:17
ミスったWDだww
typedef list< pair<string, string> > PairList; PairList l; (略) it = lower_bound(l.begin(), l.end(), "text", cp()); 上記コードで、textとpairのfirstで比較を行いたいのですが、 Compareオブジェクトはどのようなものを作れば良いのでしょうか? struct compare { bool operator()(PairList::value_type v, string s); bool operator()(string s, PairList::value_type v); }; ではコンパイルが通りません。
たぶん string -> string const& PairList::value_type -> PairList::value_type const&
>>123 IS と WD はそんなに違わない。むしろ WD のほうが修正が進んでいる面もある。
そして IS は買わないといけないが WD はダウンロードできる。
129 :
123 :2006/11/02(木) 06:07:36
言い訳すればするほど墓穴
STL学習し始めたばかりの初心者なんですが コンテナvectorのソースコードってどうやったら見れますか?
普通にファイル開けば
ドライブのどこにあるのか分からなかったのでvectorで検索かけたんですけど 同じファイルが3つくらい引っかかって、しかもテキストで開いたら文字化け気味だったので…
>>135 すみません、わざわざありがとうございます
すごく助かりました!
namespace detail { } ってどういう時に使うの?
>>137 詳細を別の名前空間に分けておきたいとき。
>>137 スレ違いに気付かない程度の人には関係ありません。
140 :
デフォルトの名無しさん :2006/11/04(土) 13:37:59
iteratorを適当に与えると行の始まりまで移動させる関数をかいたのですが std::reverse_iterator(STLport4.6.2 5.0.2) のバグと思われる実装が原因でうまく動きません。 STLport-4.6.2/stlport/_iterator.hの77行目からのoperator*なのですが _Iterator __tmp = current; return *--__tmp; となっていてデクリメントするのは間違いだと思います。 return *__tmp; とすると私の関数は希望どうり動くのですがどのような意図でしょうか? かいた関数は以下のとおりです template<class It>It& begin_line(It& it, typename It::value_type nl='\n') { typedef std::reverse_iterator<It> rit_t; for(rit_t rtmp(it); rtmp != rit_t() && (*rtmp != nl); ++rtmp) { it = rtmp.base(); } return it; }
>>140 最後の要素の次を参照する end() で reverse_iterator を初期化したとき、
最後の要素を参照しなければならない。
142 :
140 :2006/11/04(土) 15:40:21
endで初期化したならreverse_iterator的にもendだと思っていました ありがとうございました
>>140 > rtmp != rit_t()
この条件何?
実は引数が一番最初の行でbeginとかより前に行ったときループから抜けれるようにじゃね?
でも実際はこれじゃダメだよね?
>>145 reverse_iteratorから呼び出されるであろう140によるIt::operator==とかの実装によるとしかいいようがない
STLがMT safeかどうかどうしたら分かりますか?
ベンダーに問い合わせる。
2次元のvectorをサイズを指定して作成する方法を教えてください。
>>149 vector< vector<Type> > v(n, vector<Type>(m))
ありがとうございます。 2次元はうまくいったのですが、3次元に拡張しようとしたところうまくいきません。 vector< vector < vector<Type> > > v(n, vector<Type>(m, vector<Type>(n))) と書いたのですが、どこが間違えているのでしょうか?
vector< vector < vector<Type> > > v(n, vector<Type>(m, vector<Type>(n))) ↑ここがまずいのでは vector< vector < vector<Type> > > v(n, vector<vector<Type> >(m, vector<Type>(n)))
algorithmのstd::copyって例外安全ですか?
いいえ
>algorithmのstd::copyって例外安全ですか? という質問もおかしいし >いいえ という回答もおかしい
ド素人の俺が勘で答えてみると、 ・実装による ・使うコンテナによる
基本的には以下が必要 ・イテレータの前進・比較・間接参照・コピーコンストラクタ・デストラクタが例外を発生させない ・要素の代入・デストラクタが例外を発生させない ってとこかね。 コピーを巻き戻しできないので処理中に例外が発生したらあぼんぬ。
>>157 規格ってのがあるだろ。
実装によるなら一般的にはスレッドセーフでないことになる。
使うコンテナによるならやっぱりスレッドセーフでないことになるだろ。
=====>スレッドセーフでない。
GCCの実装を見る限りではスレッドセーフでなないな。
ただコンテナの代入演算子を使ってるだけ。
コピー作ってスワップってのはしてない。
スレッド?
>>158 それは「例外安全ではない」ではなくて、「基本的な例外安全」が保証されている状況
C++ 標準規格としては std::copy というか, uninitialized 系を除く アルゴリズムの例外安全性に関しては何も規定していない…… んですが,あくまで一般的な実装の話として std::copy は, iterator の value_type のコピー代入が strong guarantee を保持していることを (唯一の) 型に対する要件とした上で, basic guarantee を達成する,という説明になるんじゃないでしょうか? iterator の各操作が例外を投入しうる場合でも basic guarantee は達成すると思います.
vectorについて質問なんですが struct kobunrui{ public: std::string itemname; int kosuu; } struct daibunrui{ public: std::string bunruimei; kobunrui itemsyousai; }; 大分類についてはpush_backで追加できるのですが 大分類1個の中の小分類を追加するのは、どのようにすればいいのでしょうか? また大分類1個の中の小分類の数の取得はどのようにすればいいのでしょうか?
>>163 例えば要素0個目なら
v[0].itemsyousai = kobunrui_hensuu;
165 :
デフォルトの名無しさん :2006/11/17(金) 22:11:04
>>163 意味が判らん。
daibunruiはkobunruiのインスタンスを一個だけ持つっていう仕様
なのにそれを追加なんてできる訳ねーだろ。
struct daibunrui {
public
std::string bunruimei;
std::vector<kobunrui> itemsyousai;
};
に直せ。
daibunrui instance;
size_t index(3);
int kosuu = instance.itemsyousai[index].kosuu;
で小分類の数の取得ができる。
取り敢えずオブジェクト指向がまるで理解できてないみたいだから
もっと勉強しろ。
166 :
163 :2006/11/18(土) 02:43:52
>>164 >>165 std::vector<kobunrui> itemsyousai;
};
に直せ。で,できました
ありがとう。
オブジェクト指向とは関係ねえ ただのコンテナの問題だ
168 :
デフォルトの名無しさん :2006/11/18(土) 03:36:01
>>167 クラス設計や質問内容見りゃあオブジェクト指向がまるで理解できてない
ことぐらい直ぐ判かんだろカス。
しつこいな 何か癪に触る事でもいいましたっけ
っ 旦~
171 :
デフォルトの名無しさん :2006/11/21(火) 09:15:51
STL初心者です #define containtype list //#define containtype deque class test { containtype m_buffer; }; こんな感じで互換性のあるクラスを切り替えて使えるコードを 書きたいのですが、どうやってそれを実現するのが良いのでしょうか? ご教示くださいませ よろしくお願いします。
>>171 class test
{
typedef list<T> buffer_type;
//typedef deque<T> buffer_type;
buffer_type m_buffer;
};
174 :
デフォルトの名無しさん :2006/11/23(木) 20:26:55
イテレータのループをまわす時に継続条件として it != last と比較するのはなぜなんでしょうか it < last にしない理由がよくわかりません 「同じモノを指しているかどうか比較できる」が 「イテレータの大小比較はできない」パターンがあるという事でしょうか
はい。
一番判りやすい例は、双方向リンクリストでポインタの大小関係は あくまでメモリ上の位置だけでリストの順番とは無関係
177 :
174 :2006/11/23(木) 20:36:53
>>175 >>176 そういわれればそうですね
配列やvectorしか頭になかった・・・
リンクリストのイテレータ比較しても意味ないですね
178 :
初心者 :2006/11/23(木) 23:37:51
こんにちは。質問です。STLというのはどこでDLできるのでしょうか。 なるべく粗相のないよう簡潔にお答え願います。 注:私の有意義な発言に対し、自分の理解不足を棚に上げ煽り、1行レス で返す方が多いようですが、そのような方はスレの皆様を混乱させるだけでなく スレの雰囲気を崩しかねないのでお黙り下さい。 また質問者は回答者に知識を披露する場を与える貴重な存在なので、 質問者を見下した回答、あまりにも儀礼を欠いた回答も厳重に禁止いたします。 忙しい中、少ない時間の合間を縫って質問しに来てるわけですので、 その辺ご承知下さい。なお、当方が質問に対して有意義な答えであると 判断した方には評価いたしますので各自よく調べ、よく考え正確な回答を するように。
こっちにも来たのかww 20世紀梨キャラメル吹いた
>>178 現在の標準C++に準拠した処理系にはもれなく付いてくる。
付いてこないようであれば、そんな処理系窓から投げて捨ててしまえ。
勿論、質が問題になることはあるが。
>>178 (´・ω・`) n
⌒`γ´⌒`ヽ( E)
( .人 .人 γ ノ
ミ(こノこノ `ー´
)にノこ(
いいえ、K○s○○a○eではありません。
そういうことにしておきたいんですね :-)
と言うことにしておいたうえでこの狸うるさい上に粘着なんてイラネ
>>187 注:私の有意義な発言に対し、自分の理解不足を棚に上げ煽り、1行レス
で返す方が多いようですが、そのような方はスレの皆様を混乱させるだけでなく
スレの雰囲気を崩しかねないのでお黙り下さい。
また質問者は回答者に知識を披露する場を与える貴重な存在なので、
質問者を見下した回答、あまりにも儀礼を欠いた回答も厳重に禁止いたします。
忙しい中、少ない時間の合間を縫って質問しに来てるわけですので、
その辺ご承知下さい。なお、当方が質問に対して有意義な答えであると
判断した方には評価いたしますので各自よく調べ、よく考え正確な回答を
するように。
うざいんであぼーんした
190 :
デフォルトの名無しさん :2006/11/26(日) 03:02:39
任意の構造体を格納できるリングバッファを作ろうと考えています。 2つのスレッドがあって、一方が任意の構造体データを追加し、他方が取得します。 取得が遅いためにバッファが一杯になった場合、追加側はブロックさせたいと思います。 スレッドの排他やブロックおよびブロックの解除を実装する必要はあると思いますが リングバッファくらいならSTLにあるような気がしていて、あるならそれを使って実装しようと考えてます。 STLで任意の構造体をリングバッファに納めるコンテナはありますか? また速度は(自作するよりは)高速でしょうか?(主観でOKです。)
>>190 deque または queue で済むんじゃないかな?
>>191 ありがとうございます。早速調べてみます。
STLの入門用サイトって需要あると思いますか?
>>193 もうたくさんあるから、要らないと思う。不正確な内容のものも多いけど、
正確さを求めるならリファレンスっぽいやつや、規格を見るし。
>>194 そっか、勉強がてらに書いてみようと思ったんだけど
>>195 そういう目的があるんなら、書いたらいい。
突っ込みとそれに対する改良を重ねる前提で公開するというのは
新しいかもしれない。
stl wiki japanese
STLはできて結構時間たってるが まったく枯れてないのでやる価値はある 書籍もSGI STL前提なのでどれも古くなっている
後々の発展的な内容としてboost::bindくらいはあってもいいと思う。TR1にも入っているし。 197案のwikiをやるならSTLに限らず標準ライブラリ全てを対象にしてほしい。
>標準ライブラリ全てを対象にしてほしい。 禿同。
localeとか系統立てた解説ないしな…
localeの解説は欲しいな
Rogue Wave のユーザーズガイドにあるじゃん
204 :
デフォルトの名無しさん :2006/11/27(月) 22:46:51
std::strstream みたいなストリームクラスで、std::string みたいに可変長のバッファを取り扱えるものはないですか? 内部でバッファを持っていて、データを書き込むたびに、バッファが足りなくなったら確保してくれる・・・みたいなやつです。
std::stringstream
>>205 調べてみます、ありがとうございました!
みんなでwikiらない?
Wiki(゚听)イラネ STLの本を2冊も買えば十分じゃないか
仕様書嫁。それ以外の多くの文献は、あてにならん。 もちろんあてになるものを作ろうという動きは面白いと思うが、 Wiki は情報の信頼性が低下する傾向にあるので、俺は好かん。
俺はあっていいと思う。 既刊の書籍があれば誰にとっても十分とは思わないし、 単なるまとめサイトとしてだけでも価値を持ち得る。
何かやる気があるなら、先に cppreference の日本語訳を最新にしてくれ。
いつからストリームI/OがSTLになったんだ。
最近 STL がなんだかがっくりしているように見えてきた
長い髪が、こう、顔の前にブァサっと来てる感じか。貞子風に。
220 :
デフォルトの名無しさん :2006/11/28(火) 19:06:05
xstringについて質問なんですが、 Vc7\includeの下とVc7\crt\srcの両方にあるんですが、 現在、私のプログラムでこの二つを勝手気ままに呼び出しててえらいことになってます。 どちらか一方だけを呼ぶことってできるのでしょうか?
vc7\crt\srcをincludeに含めてるってこと? アホか
あるソースでは #include <Vc7\include\xstring> になってて、別のでは #include <Vc7\crt\src\xstring> ってなってるとか?
ワロスw まさかとは思うがそれなら自分で変更しろよww
224 :
初心者 :2006/11/29(水) 01:40:11
質問です。Standaado Tenplate Libraryを使って作りたいのですがどうすればよいのでしょうか? 注:現在、私は公私ともに多忙を極め、スレを見ることが困難な状況です。 しかしその中でも何とか時間を作り、このスレに出向いて質問をしています。 そのような貴重な質問者に対し、1行レス、煽り、罵倒で返す愚か者がいるようですが 私のような質問者がいなければそもそもあなたたちの知識をひけらかす場が 存在しないことをよく認識し、身の程をわきまえるべきであります。 よって、私のような貴重な質問者に対し、見下した回答、儀礼を欠いた回答 (例:質問してくれてありがとうございました等のお礼がない、である調で答える、 様をつけない、w等の意味不明な言葉を発する)を禁止いたします。 ましてや自分の立場もわきまえず逆にお礼を強要したり、各人の目に触れやすくなるよう 多数のレスに同様の質問をしているのを「マルチポスト」呼ばわりするような輩は 当然加害対象として私のリストに載ることになります(賢い方は意味がおわかりでしょう) この規則は2chの精神にものっとっており、強制的に施行されます。もし違反した場合には 2ch管理人への通報、加害届けの提出、プログラムのハッキング(私には 2ch専門のハッキング部隊と契約を結んでおり、銀行の口座のハッキングから FBIのコンピュータのハッキングまでこなす例のあれと親密な関係です)等断固たる処置 を取らせていただきます。また、形式的にはちゃんとした回答であっても、知識不足のため 不正確な知識を回答することも禁止いたします。よく考え、よく調べ、正確な回答を するように心がけましょう。なお、当方が質問に対し多少は役に立つと判断した場合は それなりに評価するのでご安心下さい。なお、確認はこの啓蒙文を読んでいることを 前提としており、読んでいない、理解できない等のいいわけは一切通用しません。 また、有識ある諸君は今後自分の発言に対しこの啓蒙文をコピペすることが義務になります。
あぼーんした
>>225 でましたね。啓蒙文にしっかり書いておいたのにこういう輩が。
おそらく私に対抗しうる人物は国家権力を使えるということでしょうが
こちらは世界権力を行使できる立場にいます。
国連をご存じでしょうか?そう、あのアメリカさえも畏れる恐怖の世界組織です。
私はそこと内通しており、今回のような自体には世界権力の行使も辞さない構えです。
おいおい、深夜にわらかすなよw
マジレスすると、Standaado Tenplate Libraryというものは未だこの世に存在しないはず。 少なくとも俺は聞いたことが無い。知っている奴は是非とも名乗りを上げてくれ。 さて、存在しないということはこれから作られるということだ。 つまり、224が自分の思い通りに描けば、それがStandaado Tenplate Libraryになる。 それが芸術というものではないだろうか。
正直面白いwwww
>>224 >2ch管理人への通報、加害届けの提出、プログラムのハッキング(私には
>2ch専門のハッキング部隊と契約を結んでおり、銀行の口座のハッキングから
>FBIのコンピュータのハッキングまでこなす例のあれと親密な関係です)等断固たる処置
>を取らせていただきます
通報しました。
229のマジレスに惚れた
233 :
デフォルトの名無しさん :2006/12/01(金) 07:55:16
STL語ろよ
STLゴロよ 最近はそんな商売もあるのか。
235 :
デフォルトの名無しさん :2006/12/03(日) 11:48:02
テンプレートのインスタンス化結果を ソースレベルで表示できるコンパイラってありますか? template<typename T> void foo(T arg){ cout << T; } foo<int>(50); を void foo(int arg){ cout << arg; } に展開してくれる様な この機能があればテンプレート絡みの意味不明なコンパイルエラー の修正が、かなり楽になりそうなんですが・・・
VC8のエラー表示は十分分かりやすいと思うけど 普段使ってるコンパイラはどんなエラー表示を出すの?
>>235 の質問にはそんなコンパイラ知らないだけど、テンプレートのエラーで悩むくらいならいっそ使うのやめたほうがいいと思う。
238 :
236 :2006/12/03(日) 13:18:24
>>237 いやーでもVC6の呪文のようなエラーだったら挫折しても仕方なくない?
effective STLでもエラー表示を理解しようみたいな項目があったくらいだし
239 :
235 :2006/12/03(日) 13:52:47
いやー自分で作ったテンプレートライブラリならわかるんですけど boostとか使用していて特殊化やオーバーロードが絡んでくると エラー解析に時間がかかって・・・ さんざん悩んでタイプミスでした。とかたまにあるんで ちなみにVC6使ってるのでVC8に変えてみます
まあ、俺も初めて std::string を知ったばかりのころは、 basic_string ってなーに? traits?? allocator??? ヽ(`Д´)ノ だったな
242 :
237 :2006/12/03(日) 19:58:04
たしかにSTL関連のエラーはわけ分からんな。 ただ、大量にエラー出るわりに、ミスってるのは一箇所とかだったりするんで見慣れてると何とかなるかも。 まあ、経験論なので参考にはならんな。
まあアロケータだのコンテナだの細部まで理解しなくても簡単かつ安全に使えるようなライブラリがかける ってのがオブジェクト指向の目指してることだと思うんだけどね。
STLとオブジェクト指向は関係ないと思うが
>>245 お前
>>243 か?お前みたいなオブジェクト指向を勘違いしてる奴が多いから
巷に間違ったオブジェクト指向の知識があふれてるんだよ。STLってのはジェネリックプログラミング
のC++での実装方法であってオブジェクト指向とは何の関係もない。
>>246 俺も日頃そう思っていたところだ・・・。正直オブジェクト指向も分かってない素人はプログラミングをやるべきじゃないと思う。
何この流れ('A`)
ジェネリック指向とオブジェクト指向の関係を的確に言い当てると…↓↓↓
アルゴリズムとデータ構造をパッケージングしたクラス、それがSTL。
こういう言葉の定義とかになるとやたらハッスルする人ってよくいるよね
オブジェクト指向的ジェネリック指向まだー?
ジェネリックはオブジェクト指向とは関係ないと思うがSTLはオブジェクト指向で作られてるやん。
>>256 違う。STLはジェネリックプログラミングを用いているがオブジェクト指向は
用いていない。端的なポイントを挙げるなら、仮想関数に基づいていない。
継承と動的多態がないものをオブジェクト指向と呼ぶのは、
>>246 の言う巷に溢れる間違い。
(言語によっては多少異なった形で実現されることもあるのがややこしいところだけど)
正直オブジェクト指向とか出てくるとこういう定義厨がでてくるからうざい
>>258 何を根拠にそんな不可解な定義を信じてるの?
RUBY最強杉!!!
>>260 258ではないけど、お前は何だったらオブジェクト指向と言うと思うのか?
>>256 258によれば(と言っておく)、クラスを使っているからといってオブジェクト指向プログラミングではないぞ。
スレ違いだからほどほどを願いたいが 「便利なクラス」を作ることがOOだと主張する困ったちゃんはちょくちょく見る
スレ違いだからほどほどを願いたいが OOというといきなりその定義を延々と語り説教を始める困ったちゃんはちょくちょく見る
スレ違い。OOがどうとか話してる低レベル野郎はどっかいけ
オブジェクト指向云々以前にさ
>>243 >まあアロケータだのコンテナだの細部まで理解しなくても簡単かつ安全に使えるようなライブラリがかける
これはSTLのことを指して言ってるの?
どうでもいい使い捨てのコードを書く場合は確かに細部を気にせず使うけど、
仕事で使う場合は結局STLの細部まで知っている必要がある気がする。
268 :
258 :2006/12/04(月) 01:42:54
>>260 不可解かな。根拠は、例えばこのへん:
ttp://en.wikipedia.org/wiki/Object-oriented_programming → "1 Fundamental concepts"
オブジェクト指向プログラミングを特徴づけるものは7つ。クラス、オブジェクト、
メソッド、メッセージ送信、継承、カプセル化、抽象、多態(ポリモーフィズム)。
これらを備えるものをオブジェクト指向言語と呼ぶが、場合によってはいくつかを
欠く。
ダメ情報源でなければ、およそ似たことが書いてあると思う。
STLはtemplateによる静的多態性に立脚しているわけで、
STLそれ自体は動的多態性を旨とするオブジェクト指向とは異なる作りをしている。
ユーザがオブジェクト指向とSTLを同一プログラム内で使い分けるのは自由だけどね。
>>268 リンク先にだいぶマシな定義が書いてあるじゃねーか。
"Object-oriented programming (OOP) is a programming paradigm that uses abstraction to create models based on the real world."
引用した箇所にあるのは「オブジェクト指向言語」についての説明で、
しかもいくつかを欠いたものも「オブジェクト指向言語」に含むことになっている。
何を以って「オブジェクト指向(プログラミング)」と呼ぶかの定義にはならない。
多態だって動的か静的かの区別なんてしてないだろ。
なんでおまえらは荒れるとわかっててその話題をスルーしませんか
このスレは要らないと思ってるから。
コードの多態っぷりはまさにオブジェクト指向っぽいんだが ランタイムに動的ディスパッチしないと一部の人は納得しないんだろうなあ
273 :
258 :2006/12/04(月) 02:46:50
>>269 > リンク先にだいぶマシな定義が書いてあるじゃねーか。
> "Object-oriented programming (OOP) is a programming paradigm that uses abstraction to create models based on the real world."
ここまでで止めると曖昧すぎていまいちじゃね?
> 引用した箇所にあるのは「オブジェクト指向言語」についての説明で、
> しかもいくつかを欠いたものも「オブジェクト指向言語」に含むことになっている。
要約が悪かったせいですまんが、引用の前の文がOOPに関する説明で、
後ろの文が言語に関する補足。よくわからん向きは、長いけど原文読んでくれ。
> 多態だって動的か静的かの区別なんてしてないだろ。
んーむ。確かにそうだね。言語によらない元々の定義は動的静的を区別しないのかも。
C++でのより狭義なOOPの定義は、Stroustrup の C++ Glossary に記載がある:
ttp://www.research.att.com/~bs/glossary.html#Gobject-oriented-programming object-oriented programming - programming using class hierarchies and
virtual functions to allow manipulation of objects of a variety of
types through well-defined interfaces and allow a program to be
extended incrementally through derivation.
んで、クラス階層と仮想関数を使わずにユーザ型だけに基づいて行うプログラミングは
データ抽象(プログラミング)と区別して呼んでる。
てことで、
>>258 の記述は「C++での定義では」という注釈をつけないと
いまいち正しくないかもね。
>>270 能力の無さを、必死さとか粘着質とかでカバーして
それなりに「論陣張ってるっぽく振る舞える」話題だからだよ。
普通の「出来る奴だけが輝ける」話題で一切まともなこと言えない馬鹿が
ここぞとばかりに頑張ってる。
「自分の居場所を見つけた!」ってね。
real worldってまだそんな妄想を語る奴がいるのかよ 信じられん
流れ自体がどうでもいいから、ここでもどうでもいいこと言うぜ 知ってるやつも多いだろうが 今年の基本情報の問題に "自動車のサブクラス" を問う問題が出たんだ… さすがに内心笑ったやつは多いと思うよ…
全然ダメだな やっぱオブジェクト指向は”動物クラス”から”犬クラス”と”猫クラス”を派生させないとね! そして多態で鳴く
実務に関係ない喩えで出題してんのか・・ まあ基本情報はそんなものだろうけど
大切なのは概念…って馬鹿かって感じだわな。
オブジェクト指向:関連するデータ構造とアルゴリズムを乖離させないのが目的。クラスその他は実現のための手段 じゃだめなの? 多態性の本質を的確に教えてくれ(´・ω・`)
>多態性の本質を的確に教えてくれ(´・ω・`) インタフェイスと実装の論理的な分割じゃねーの。 実装が変わっても、インタフェイスが同一であれば接続可能。
クラス使えればオブジェクト指向かとおもってたよorz 具体的にコード書くのは仕事やってればいやでも身につくけど こういうのは自分で勉強しないとだめだからねぇ・・・ 今からでもまじめに勉強しようかな
>>284 もっとましなスレを出せよ。やはり嵐か?
話をSTLに戻そうっていってるだけなのに荒らし扱いなんかよ・・・ OO厨は怖いな・・・
そりゃお前、「俺はこんなにもわかってる奴なんだ」ってのを 必死でアピールする場を奪われちゃたまらないだろう。
>>284 がもっとマシなスレを出していればねぇ('A`)
至高スレなくなっちゃったしなぁ。
RUBYYYYYYYYYYYYYYYYYYYYYYY!!!!!!!!!!!!!!!!!!!!!!!
しーしゃああああああああぷうううううううううううううううううううううううううううううううううううううう!!!!!!!!!!!!!!!!!!!!!!!!!!!
しいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
RubyがC++よりはるかに優れているのは自明であって 今さらそんなことで荒らしに来るRuby信者なんか居ないから 騙っても無駄だよ。
>>293 騙りも何も君みたいなのがいるじゃない^^
293みたいなまともな人間がいる、から、なに?
RUBYを知らない者はオブジェクト指向を知らず、という格言もあることだし。
言語が優れてるだの劣ってるだのいってる人間がまともなのか・・・ 言語のある特定の部分、という点ならわかるけど。
ようするにD言語マンセーと。
なにいってんだE言語だろ
print_anyでコンストラクタを直接呼んでオブジェクト渡してますが、参照を渡していないのに slink_iteratorのコンストラクタが2回しか呼ばれないのは、なぜでしょうか?いるんでしょうか? 以下ソースコード template<class Iterator> void print_any(Iterator first, Iterator last) { while ( first != last ) { cout << *first << ' '; ++first; } } class slink_iterator { slink_of_int* cursor; public: // コンストラクタ explicit slink_iterator(slink_of_int* p =0) : cursor(p) {cout << "Constractor" << endl;} ~slink_iterator() { cout << "Destractor" << endl; } // '++' 演算子 slink_iterator& operator++() { cursor = cursor->next; return *this; } // '*' 演算子 int operator*() { return cursor->data; } // '!=' 演算子 friend bool operator!=(const slink_iterator& x, const slink_iterator& y) { return x.cursor != y.cursor; } }; int main() { print_any(slink_iterator(&s1),slink_iterator()); return 0; }
301 :
デフォルトの名無しさん :2006/12/06(水) 00:24:28
>>296 RUBY信者のキモさを見事なまでに表現した格言だな。
RVOとは違うんだっけ?
Rubyは完全オブジェクト指向でRuby使えると大体下位互換のC++とかPythonとかJavaは 簡単に使えるようになるから東大の教養学部でもRuby教えるようになったんだよね。
C++はオブジェクト指向「も」使えるだからね。正直C++で書いてるという人の9割はオブジェクト指向 というものを分かってないと思う。Ruby自体はオブジェクト指向に関してはC++より圧倒的に優れてるけど いかんせんスクリプト言語だから遅いんだよね・・・ まあ最初に勉強する教育目的の言語ではRubyの方がいいと思うが。
Ruby みたいな低級言語ですら Ruby では書けない。 その程度の記述力、実行効率。
低級っていうのは言語としてよりネイティブであるということですが・・・(笑) まあ揚げ足取りはさておき、少なくともネイティブアプリをかけること自体は 今はそんなにマイナスポイントではないね。そういうのは一部のハッカーが書けばいい。 RubyとかJavaがCとかC++に比べて今世界でもっとも広く使われるようになってきたのは そういうネイティブコードよりも可読性、オブジェクト指向との親和性が高いからだしね。
rubyがC++より圧倒的に優れてるのは当たり前だがそれはスレ違いだろ・・・
いやまぁそれは同意するけど、可読性の高い良い言語でもやりたいことが 妥当な性能で出来なきゃ使えないってことも事実なわけで。
でも性能が必要な現場なんてそうそうないような・・・ それに数値計算以外はrubyはCに匹敵する速度が出るし 特にネットワークアプリとかをわざわざ他の言語で書く理由がみあたらない。 スレ違いスマソ
>>309 >でも性能が必要な現場なんてそうそうないような・・・
ここ C++ のスレだから、基本的に性能が必要な現場の人が語らうとこだと思う・・
なんだこの流れ・・・
Rubyへの嫉妬心が、 普通ならあっという間に流れて終わるだけの限りなく独り言に近い書き込みを ここまでのホットトピックに育ててしまったのです。
ルビ厨復活か? Del厨は結局復活しなかったな
ネタが無いから一人で煽ってるものとばかり
>>300 デフォルトコピーコンストラクタが呼ばれてるんじゃないの?
>>303 シラバス検索してみてもヒット0件だったが。
11/3の日経一面に出てたね。来年からだって。
下位互換・・・・・
>>303 rubyってdefine や templateとかもあんの?
オブジェクト指向型の言語やってりゃJavaとかの習得が楽ってのはわかるけど、
それだけじゃC++を使いこなすには足りないと思うし。
STLとはあんま関係ないけど自分でTemplateクラス書くときってFriend関数使う? それともFriend関数はなるべくないようなクラス設計を目指す?
>>321 使う。A.Alex が述べてたように、SmartPtr みたいなものだとメンバ関数より、
フレンド関数の方が都合がいい。
さらには、↓の理由からフレンドを使うこともある。
template< typename A > void indirect_call( A & a ) {
...
do_something( a ); // a.do_something() だと、A が限定される。
...
}
>>322 あーまさに後者の場合が問題だったんだよね。こういうときも無理矢理でもfriend使わないような
設計にしちゃった方がいいのか気になってた。
レスありがとう!
324 :
デフォルトの名無しさん :2006/12/07(木) 12:02:35
C言語で構造体のコピーってmemcpyでやってましたが、 C++で構造体にstd::stringメンバが入ってる場合の構造体コピーってどうやるんでしょうか?
C でも C++ でも、構造体のコピーには代入を使っておけばいい。
326 :
デフォルトの名無しさん :2006/12/07(木) 20:01:50
またインストールせねば・・・
もうSTLportの役目は終わっただろ
>>328 _STLP_NO_EXCEPTIONS をと同等の設定をわざわざサポートしてくれるコンパイラベンダは無さそう。
>>328 状態を持つアロケータをサポートしてくれたのは大きいだろう。
フツーのSTLのアロケータの実装は、なんちゃってシングルトンってこと?
>>333 そんなところ。
インスタンスをコンテナごとに持つところまでは決まってるんだけど、
同じ型のインスタンスを区別して扱うことを標準が強制しておらず、
現行の実装はそのことに依存してしまっているものがほとんど。
list a, b があって、これらが異なるアロケータインスタンスを使っているとき、
splice() を使って a <-> b 間で部分的な要素を受け渡すと面倒なことが起こるはず。
標準が強制しなかったのも理解できるし、 STLport の実装も(まだ見てないけど)興味深い。
てすてす
質問です。 multimap利用して同一キーに複数の値をinsertしたとき iterator itr = lower_bound(key) のあと itr++の順番で値を表示していく場合 insertされた順番に表示される、でいいのですか? なんかうまく表現できないけど察していただけるとうれしいです。
set<int> a; a.insert(5); setのaがあって、全ての要素に10を足す、ということをやろうとしてます 一応↓これで動く(ちゃんと15が表示される)のですが transform(a.begin(),a.end(),ostream_iterator<int,char>(cout,"\n"),bind1st(plus<int>(),10)); aのデータの中身も変更したい時はどのようにすればよいのでしょうか 次のように書くと、5が表示されてしまいます for_each(a.begin(),a.end(),bind1st(plus<int>(),8)); copy(a.begin(),a.end(),ostream_iterator<int,char>(cout,"\n"));
>>337 setは中の値を使ってデータを並べてるんだから書き換え不可。
新たなsetを作り直すしかないと思う。
足したい値が負なら要素の小さい方から、正なら要素の大きい方から足して要素並びを保証すればいいじゃない set<int, less<int> > a; for (int i = 0; i < 10; ++i) {a.insert(i); } //要素の後ろから足す transform(a.rbegin(), a.rend(), inserter(a, a.begin()), bind1st(plus<int>(), 10) ); copy(a.begin(),a.end(),ostream_iterator<int,char>(cout,"¥n"));
>>336 multiset/multimapでは同値なオブジェクト同士の順番に関する保証はない
>>336 それらしい記述が見つからないから未定義かもしれん。
342 :
341 :2006/12/13(水) 22:37:00
やべ
343 :
337 :2006/12/14(木) 08:53:30
>>338 ,339
なるほど、ちょっと理解が深まりました
一度データを追加&削除で対応することにします
ありがとうございました
344 :
336 :2006/12/14(木) 13:17:44
並び順に関する保証はないですか・・・ ファイルの内容を読み込んで、いくつかの種類に順番に分類するとしたら 順序コンテナを分類する数だけ用意するほか無いのでしょうか?
std::map<Key, std::list<T> > でええやん
vector & stable_sort & equal_rangeもあるな
intやdoubleをstring型にしたいんだけど 一度sprintfなどでchar*にコピーしてからコンストラクタに渡すしか方法はないかな
boostを入れてたのを思い出したのでlexical_castで解決しますた けど、boostない環境では普通にsprintfやstringstream経由でないと不可能?
>>348 Exceptional C++ Style の最初の項を立ち読みしてきなさい
>>348 boostのソースを読んでみればいいじゃないか。
普通にstringstream使ってるだけだぜ?
つうかstringstreamの何が不満なのか
標準をそのまま使うのが急にダサいと感じ、ズレたものを好むようになる・・・中二病?
強いて言うなら速度とかメモリ消費量?
速度とかメモリ消費量を無意味に気にして、保守性を低下させる・・・中二病?
速度を重視すべきな場合STLは使うべきではないのでしょうか。 std::vectorくらいなら大丈夫だと思ってたんですけど。 でも実装によるとか言われそうだ。
>>355 使ってみて(≒測定して)から文句言え。
いよいよmove semanticsが欲しくなるな
iostream系は書式指定が面倒 というか俺が覚えてないから調べるのが面倒
359 :
デフォルトの名無しさん :2006/12/16(土) 12:12:52
>>358 覚えていても面倒だよ。
そこでboost::ほにゃららですよ、と言うといろいろ召還しそうなのでやめとく。
sage忘れごめんorz
boostっていつc++にはいるんだろうね?
boostのサイトでTR云々かいてあるのは入る予定なんじゃないの
それは時期正式リリース候補だ
俺printf使ったこと無いからiostreamの方が駱駝
STL勉強中です 次のような状況で、ファンクタが書きたいんですが こういうことって可能でしょうか nを入力すると、nの2倍とnの2乗の集合を返す関数fがあります set<int> f(int n); f(1)={2,1} f(2)={4,4} f(3)={6,9} f(n)={2*n,n^2} 集合aがあってaのそれぞれにfを適用して新たにbを作りたい 例えばa={1,2,3}だとするとb=f(a)={f(1),f(2),f(3)}={{2,1},{4,4},{6,9}} このような場合に transform(a.rbegin(),a.rend(), inserter(b, b.begin()),作りたいファンクタ); のようなファンクタを書くことはできますか もっと適しているデータ構造とかあるんでしょうか
>>365 これじゃダメなのか?
transform(a.begin(),a.end(), inserter(b, b.begin()), f);
>>366 レスありがとうございます
要領を得ない質問の仕方でした、すみません
set<int> a;
set<set<int> > b;としたら一応動くのですが
このbのデータ型もset<int>のままで動かすことは出来ないのでしょうか
(要素のほうのsetも全部親に繰り入れた感じで)
このデータ型にはとくにこだわりはなくて
ファンクタを連鎖的に適用できるような形にはできるでしょうか
一度setのsetでデータを得て、その後そのデータをsetに変更して
bにデータを代入することで目的の動作は達成できるんですが
こういう方法しかないのでしょうか
fの入力と戻り値の型が違うからこういうことになるのかと思い
set<int> g(set<int>)というのを考えたら
結局gの内部で同様の問題が起こってしまいました
次のプログラムで言えば 関数gを経由しないで集合bdashを求めるようなファンクタは書けるんでしょうか typedef set<int> SET; typedef set<SET> SETSET; SET f(int n){ SET a; a.insert(n+n);a.insert(n*n); return a; } SET g(SETSET a){ SET res; for(SETSET::iterator it = a.begin();it!=a.end();++it){ for(SET::iterator it2 = it->begin();it2!=it->end();++it2){res.insert(*it2);} } return res; } int main(){ SET a,bdash;SETSET b; for(int i=0;i<3;++i){a.insert(i+1);} transform(a.begin(),a.end(), inserter(b, b.begin()), f); bdash = g(b); copy(bdash.begin(),bdash.end(),ostream_iterator<int,char>(cout,"\n")); }
>nの2倍とnの2乗の集合を返す関数fがあります これを分けて int get_twice (int n) {return n;} int get_square (int n) {return n * n;} 2回transformするとか?
失礼 -int get_twice (int n) {return n;} +int get_twice (int n) {return n * 2;}
>>368 こう
typedef set<int> SET;
int get_twice(int n){return n+n;}
int get_square(int n){return n*n;}
int main(){
SET a,bdash;
for(int i=0;i<3;++i){a.insert(i+1);}
transform(a.begin(),a.end(), inserter(bdash, bdash.begin()), get_twice);
transform(a.begin(),a.end(), inserter(bdash, bdash.begin()), get_square);
copy(bdash.begin(),bdash.end(),ostream_iterator<int,char>(cout,"\n"));
}
>>367 set の set がただの set に変換できるの?
4 の2乗の 16 と 8 の2倍の 16 が区別できないんじゃないか?
あ、その前に set だと {4,4} からして無理だな。
>>372 それがもし問題ならmultisetにすれば解決するね
>>369 ,370
レスありがとうございます
確かにそれでうまくいきそうですね
ちょっと後出しになってしまって申し訳ないですが
今回2倍と2乗を返すという設定にしたのは、
質問内容の簡略化のため要素数が変わるような関数の例として作ったものです
実は、あるパズルを解くために
数字をn個使って作れる数の集合を求める関数というのが必要になり
この場合、2倍と2乗のように入力と出力の数が同じになるように
うまく分割することが出来なさそうなんです
(出来るかもしれないけど、自分にはわからないので・・
一応、さっきのプログラムの要領で解決はできそうなんですが
他に良い方法ってあるでしょうか
> 数字をn個使って作れる数の集合 こういう感じ? n = 1のとき{1, 2, 3, ..., 9} n = 2のとき{10, 11, 12, ..., 99}
>>371 申し訳ないです
レス書いてる間にプログラムまで、感謝です
>>372 今回は区別の必要がないので、
同じ値があったら追加しないということにしたら変換できるかなと
必要なら
>>373 さんのようにすればよいと思います
>>375 はい、イメージとしてはそんな感じです
自分が今やっているのは、
例えば加算の演算子+と、同じ数値を並べる演算子があったとして
1をn個並べる関数をfとしたら
f(1)={1}
f(2)={1+1,11}={2,11}
f(3)={1+1+1,11+1,111}={3,12,111}
というような関数です
質問があります。 typedef struct stdata{ int nNum; string sText; }LISTDATA_T; vector<LISTDATA_T> vlist; というデータがあるとして、vectorのデータ内を nNumの値でソートしたいのですが可能でしょうか?
そういう関数オブジェクトを作れば可能。 或いは全体的にnNumで比較するのが適切であれば、 operator <の定義を考えたほうが良いかもしれない。
template <class RandomAccessIterator, class Compare> void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); お使いのでこれが対応知れてば余裕。
381 :
378 :2006/12/16(土) 23:27:23
>>379 ,380
レスありがとうございます。
試してみます。
382 :
355 :2006/12/17(日) 03:34:55
容量1000の配列全要素に対してforで回して0を代入するという動作を10000回繰り返した。 配列は配列([])とstd::vectorで[]を使ったのとiteratorを使ったの3通り。 std::vectorで[]を使うと配列の時の約2.5倍、 iteratorを使うと配列の時の約1.5倍時間がかかった。
処理時間が一時間とか一日とかかかるプログラムでは致命的だな。 どうしようもない。
最適化で全くかわるね Linux GCC -O3 だと vector[] = array[] > vector::iterator > vector.at() -O1 だと array[] > vector[] > vector.at() > vector::iterator ただ、最速、最遅で4倍も違わないからどれでもいいと思う。 こんなのカスみたいなコストだ。
そりゃまぁ、ほぼ無意味なループで速度比較してもそんなもんだよな。 実際にはループ一回辺りの処理時間が増えるからますますその差の意義が薄れる。
>>382 0で埋めた後でその総和を取ったりとかしてないと、そもそもループ丸ごと最適化で消されたりするんだが。
ちゃんとやってるよな?
んでうちの結果はイテレータのみ倍遅い。あとは全部誤差の範囲。
つーか、10000回程度だと負荷が軽すぎだろ。
vectorの提供する機能と必要なコストを天秤にかけて 妥当だと思うときにvectorを使うのよね array[]で済むならarray[]使えばいいのです
内側でvolatileな変数宣言したりしてればきちんと阻害される
iteratorのforでの書き方にもよりそうだが
>>382 ,
>>387 vector<int> v;
v.resize(1000);
int *p=&v[0];
としてv[i]のかわりに *(p+i)を使えば速度は同じになる。
ループのマイクロベンチが何だというんだ。 マイクロベンチで1:2.5みたいな差が出ても アプリに落ちれば30:31.5くらいだろw
そこでvector<Is32vec4>とか
>>382 配列は代入のみでvectorはallocateと代入で、比較してる操作が
違うから当然の結果だろうね。resizeしての比較をするべきだろう。
>>393 allocateは関係なく、単純な代入だけでも差がでる。
関数をコールしている分vectorは遅いのではないか?
>>394 最適化はかけたか?デバッグオプションは付いてないか?
>>394 具体的なベンチコードとコンパイラの名前とバージョンさらせ。
>>394 inline関数が遅いなんてことはない。operator[]が
*(begin() + _Pos)なので遅い。
>>397 > *(begin() + _Pos)なので遅い。
なんでだよ
beginはinspectorだろ。
>>399 それが遅い理由なの?
ごめん。意味わかんない。 inspector って、何の用語?
401 :
394 :2006/12/19(火) 14:23:35
>>395-397 VC++7.1,stlportをマルチスレッドオプションを付けてコンパイルしている
(cl /GX /O2 /MT ...)
やはりvectorの方が普通の配列より2割ぐらい遅いね。
マルチスレッドだとアロケートがコスト(比較的)大だからなぁ・・・
403 :
394 :2006/12/19(火) 14:33:26
resizeしてから計測しているのでallocateは関係ないはず
forなんかでまわさずTSCで計ったら?
javaでいうLinkedHashMapみたいなのは自作しないと無理? 挿入順序覚えてくれてる連想配列なんだけどvectorとmap併用かしら?
とりあえずVC++7.1+付属のSTLでは、 for (int i = 0; i < 1000; ++i) array[i] = 0; for (int* b = array, *e = array + 1000; b != e; ++b) *b = 0; for (int i = 0; i < 1000; ++i) vec[i] = 0; の三つに対して、同じ lea edi, DWORD PTR _array$[esp+4064] xor eax, eax mov ecx, 1000 rep stosd というようなコードを吐いた。よってこの3者は完全に等価。STLportはシラネ
Boostにmulti_index_containerという複数の順序付けを指定できるコンテナがあるんだが、だめか?
>>407 だめ だけど勉強になりました。
ありがとう。
vectorはヒープから割り当てるから、 スタック上の配列と比べてメモリのキャッシュに乗りにくいのかな。
アロケー(ry
すみません、質問させてください 基本型あるいはユーザ定義型の配列の要素数を返す関数を作ろうとしてるんですが arrayがユーザ定義型の配列であった場合でも /* @ */の処理がコンパイルされるためエラーになってしまいます template <typename T> void count(T array[]){ if(boost::is_pod<T>::value){/* @ */} else{/* A */}} WEBで調べているとenable_ifで解決できそうな予感がしたのですが 自分には次の例がよく理解できません(特に::type*=0の部分) これはどういった理屈で動いているんでしょうか template<typename T> void copy_n( const T* from, int n, T* to, typename enable_if< is_pod<T> >::type* =0 ){/* 省略 */}
412 :
411 :2006/12/19(火) 19:49:26
あ、boostスレと間違えた^^; 向こうで質問しなおしますね
質問です。 for(vector<shared_ptr<A> >::iterator itr = a.begin(); itr!=a.end(); ++itr) { hogehoge.... } とやろうとしたのですが、vector<shared_ptr<A> >::iteratorじゃなくて vector<shared_ptr<A> >::const_iteratorで a.begin()を受けろとコンパイラに怒られてしまいました。 vector<shared_ptr<A> >::iteratorで受けたいのですが、どうすればよいのでしょうか。 vector<shared_ptr<A> >::const_iteratorをvector<shared_ptr<A> >::iteratorに変換できれば それでもよいですが・・・。
>>413 aがconstなんだろ。
const_castすればいけるだろうが、それは何か間違ってる。
>>413 vector< shared_ptr<A> > b = a;
for( vector< shared_ptr<A> >::iterator itr = b.begin(); ...
おっしゃるとおり、aがconstでした。ありがとうございました。
417 :
デフォルトの名無しさん :2006/12/20(水) 18:27:26
STLのsetを使っていて、だいたい set<X> a; a.insert(b); のようなことをやると、 Core was generated by `XYZXYZ'. Program terminated with signal 11, Segmentation fault. #0 0x400000000002f320 in std::_Rb_tree<X, X, std::_Identity<X>, std::less<X>, std::allocator<X> >::insert_unique () (gdb) backtrace #0 0x400000000002f320 in std::_Rb_tree<X, X, std::_Identity<X>, std::less<X>, std::allocator<X> >::insert_unique () #1 0x4000000000002aa0 in main??unw () のような感じでエラーになってしまうようです。 (完全に再現性のある小さいコードを用意することが 出来ませんでした。すみません。) コンパイラはicc9.0で、gccだと問題なく動作します。 個人的にはsetのinsertでcoreを吐くというのは、 あまりないような気がするのですが、どういうことを 念頭におきながらデバッグすればよいでしょうか?
まず何処で落ちてるのか、STLの中まで追っかける。
>>417 原因はsetというより十中八九
Xだろうね
420 :
デフォルトの名無しさん :2006/12/20(水) 19:08:30
とりあえず、-fastをつけずにコンパイルすると大丈夫みたいです。 -fastと-ggdbをつけてデバッグした結果です: Core was generated by `./XYZXYZ'. Program terminated with signal 11, Segmentation fault. #0 0x400000000002f320 in _ZNSt8_Rb_treeI6XS0_St9_IdentityIS0_ESt4lessIS0_ESaIS0_EE13insert_uniqueERKS0_ () at /usr/include/c++/3.2.3/bits/stl_algobase.h:747 747 if (*__first1 < *__first2) (gdb) backtrace #0 0x400000000002f320 in _ZNSt8_Rb_treeI6XS0_St9_IdentityIS0_ESt4lessIS0_ESaIS0_EE13insert_uniqueERKS0_ () at /usr/include/c++/3.2.3/bits/stl_algobase.h:747 #1 0x4000000000002aa0 in main () at /usr/include/c++/3.2.3/bits/stl_alloc.h:248 ええっと、参照されてるSTLがgcc由来のものなのが気になります。 (icc9はgcc3系と結合出来るみたいですけど) とりあえずOSはGNU/LinuxでCPUはItanium2です。
-fastの代わりに-O3 -ipoにしてみるとどうなるかな。
注:私の有意義な発言に対し、自分の理解不足を棚に上げ煽り、1行レス で返す方が多いようですが、そのような方はスレの皆様を混乱させるだけでなく スレの雰囲気を崩しかねないのでお黙り下さい。 また質問者は回答者に知識を披露する場を与える貴重な存在なので、 質問者を見下した回答、あまりにも儀礼を欠いた回答も厳重に禁止いたします。 忙しい中、少ない時間の合間を縫って質問しに来てるわけですので、 その辺ご承知下さい。なお、当方が質問に対して有意義な答えであると 判断した方には評価いたしますので各自よく調べ、よく考え正確な回答をするように。
>>417 問題の再現するソースと再現しないソースの違いを洗っていけばいいんだよ。
選択機
STLの定数(std::ios::outとか)の定義について VC6付属のSTLではenumで定義されてるけど、 VC8付属のSTLではclass _Iosbのメンバで static const _Openmodeで実体があるのはなぜ? VC6の時はstatic const に初期値を設定できないから enumハックを使用していると思うんだけど static const にして実体を持つようにした理由がわからない。 なにか利点あるの?
>>425 元々列挙値じゃないのに enum を使ってたのが不自然なんだから、
普通に改めたんだろ。逆に、何か不満な点でもあるの?
427 :
425 :2006/12/22(金) 15:36:23
enumの方が実体がない分サイズの節約になるし(微々たる量だけど) 利用する箇所でもコンパイル時に値が確定するから、 高速化しそうな気がするんですが。 (static constも最適化されて同じかもしれませんが、 それを期待するのはどうかと思って。)
>>427 サイズのデメリットは型の正しさの前では無視できる範囲だと思うよ。
サイズと引き換えにアドレス(参照)を取ることができるようになるから、
相殺と考えることもできるだろう。
static const でも、整数型(および列挙型)でクラス定義内で初期化子を
つけたものはコンパイル時定数として使うことができる。
これは規格で定められた動作なので、最適化に期待するというものではない。
429 :
425 :2006/12/22(金) 17:29:48
>>428 参照ってのは思いつきませんでした。なるほど。
型の正しさはenumでも同じですよね。
>static const でも、整数型(および列挙型)でクラス定義内で初期化子を
>つけたものはコンパイル時定数として使うことができる。
規格で定義されてるんですね。
知りませんでした、ありがとうございます。
>>429 > 型の正しさはenumでも同じですよね。
typesafe enum知らない人?
enumはあまりtypesafeじゃないよ。初級なんでググってみて。
431 :
425 :2006/12/23(土) 04:28:27
>>430 typesafe enum知らなかったからぐぐって見た。
javaばっかりヒットするのね。
Cはtypesafeではないけど、C++のenum は 型チェックしてくれるから、
typesafeなんじゃないのと思ったり。
それはそれとして、enumはtypesafeではないかも知れないけど、
static const _Openmodeで実体を持つ場合も同じではないの?
>C++のenum は 型チェックしてくれる ???
>>429 > 型の正しさはenumでも同じですよね。
組み込み整数型で特殊化した template に
enum で定義された定数を渡して特殊化版が
呼び出されないとか、困るかもしれない。
435 :
・∀・)っ-○◎●創聖のダンゴリオン ◆DanGorION6 :2006/12/23(土) 21:02:38
opに比較関数を渡してやればおk
struct comp {
bool operator() ( const char a, const char b ) const {
bool bResult;
//ここに必要な処理を書く
return bResult;
}
};
c.sort( comp() );
ファンクタを渡してやれば、逆順ソートとか文字列の大文字小文字区別無しソートとかも可能。
Windows XPのファイル名ソートみたいに、文字コード順ではなく含まれる数値順でソートやるのだって可能。
俺的にはここがいいかな
http://www.wakhok.ac.jp/~sumi/stl/index.html デスクトップリファレンス的なものは置いておいた方がいいよ。
俺が使ってるのはオライリーのC++ランゲージクリックリファレンス/C++ライブラリクリックリファレンス。
>>435 >opに比較関数を渡してやればおk
>
>struct comp {
> bool operator() ( const char a, const char b ) const {
> bool bResult;
> //ここに必要な処理を書く
> return bResult;
> }
>};
>
>
>c.sort( comp() );
>
>ファンクタを渡してやれば、逆順ソートとか文字列の大文字小文字区別無しソートとかも可能。
>Windows XPのファイル名ソートみたいに、文字コード順ではなく含まれる数値順でソートやるのだって可能。
丁寧な回答感謝します。昇順ソートだけじゃなくて
いろいろなソートが出来るんですね。
>俺的にはここがいいかな
>
http://www.wakhok.ac.jp/~sumi/stl/index.html >
>デスクトップリファレンス的なものは置いておいた方がいいよ。
>俺が使ってるのはオライリーのC++ランゲージクリックリファレンス/C++ライブラリクリックリファレンス。
私も参考にしたいと思います。
>>436 不要な引用は見づらいだけなので気をつけたほうがいいよ。
438 :
デフォルトの名無しさん :2006/12/24(日) 04:19:11
良質なSTL本を教えて下さい。 2冊欲しいと思っています。 1. STLの基本概念や、各機能の説明が分かりやすく 説明されている物(vector, mapとはどういう物かとか)。 2. STLの内部実装の事や、効率面を考えた時に、知っておいた方が良い事が纏められている様な物。 要するに、かなり深く突っ込んだ内容のものがいいです。
>>1 1.C++標準ライブラリ
ISBN4-7561-3715-6
2,Effective STL
ISBN4-89471-410-8
440 :
438 :2006/12/24(日) 04:22:57
441 :
439 :2006/12/24(日) 04:24:02
酔ってるゴメン でもISBNは合ってると思うのでとりあえずamazonで見てみて
>>441 おお、即レスありがとうございます。
早速色々と見てみたいと思います。
初心者です。わからないのですが教えてください。
イテレータのスコープがよくわかりません。 同一関数のスコープ内で同名で違うイテレータを定義した場合、前に定義したイテレータは消えるようですが、 宣言としては、グローバル変数や引数と名前がかぶらないように注意するだけでよい、ということでしょうか?
定義って何? typedefのこと? それとも実体をつくること?
446 :
444 :2006/12/24(日) 12:27:51
失礼しました。実体のほうです。たとえば、2つのベクトルの最大値を求めたい場合、 vector<T> vect1, vct2; (データを代入) vector<T>::iterator k = max_element( vct1.begin(), vct1.end() ); vector<T>::iterator k = max_element( vct2.begin(), vct2.end() ); とするわけですが、このときのイテレータkのスコープを知りたい、ということです。 STLは勉強し始めたばかりなので、何かへんなことを聞いていたら申し訳ないです。
そっちか。
STL関係ない。
「イテレータ」を「変数」に置き換えて
>>444 を復唱してみろ。
448 :
・∀・)っ-○◎●創聖のダンゴリオン ◆DanGorION6 :2006/12/24(日) 12:38:16
コンパイル通るかどうか試してみましょう。 通らないものを作っても無駄な作業でしかないです。
449 :
444 :2006/12/24(日) 12:43:16
>>447-448 もちろん、通ることは確認済みなのですが、理屈がわからずに使うのは気持ち悪い、と思いまして確認させていただきました。
イテレータのスコープはローカル変数と同じと考えてよい、ということですね。
ありがとうございました。
>>449 同じスコープで同名の変数は定義できないよ。
どんなクズコンパイラ使ってんだ?
それに、結論も違う。「イテレータの値をローカル変数に入れている」と考えろ。
そうなればスコープについてローカル変数のルールに従うのは自明なはず。
イタレータに限らずオブジェクトにスコープという概念はないよ。 スコープを持つのは、宣言や定義。 オブジェクトはエクステント(extent)。普通生存期間と訳されている。 この区別は、言葉だけの問題ではなく、基礎概念の理解につながっている。
STLが使えて
>>446 がコンパイル通るコンパイラっていったいなんだろう…。
んなもんあるわけねーだろ 通ったってのはウソだよ
彼女いなくてもtypo位許してやれよ
455 :
444 :2006/12/24(日) 14:54:32
>>450 vector<T> vect1, vct2;
(データを代入)
vector<T>::iterator k = max_element( vct1.begin(), vct1.end() );
k = max_element( vct2.begin(), vct2.end() );
でした。すみません・・・
>>450-451 については、基礎的概念をきちんと勉強してステップアップにつなげたいと思います。
ハウツー本ばかりの自我流で、まともな概念書を読んだこともなかったので。
今、「STLによるC++プログラミング」2rd,マッサー他 を読んでいるのですが、敷居が高いっす。
ネットのハウツー参考にしながら感覚的には理解し始めているのですが・・
>>455 一般的な変数のスコープとオブジェクトの生存期間について理解してからSTLに取り組むことをお勧めします。
>>455 君のそのコードは
int hoge = 10;
hoge = 5;
と何が違うんだい?
458 :
・∀・)っ-○◎●創聖のダンゴリオン ◆DanGorION6 :2006/12/24(日) 16:16:37
そもそもCをわかってないのにSTLを使おうとしてないかな
そもそもsageを分かってないのにスレに書き込もうとしてないかな
頭の悪い切り返しにもほどがあるな
>>392 見ればsageを知らないわけではないことくらいわかるだろうに
チェック抜けてただけなんだよね
そこは気付よ
464 :
デフォルトの名無しさん :2006/12/25(月) 22:02:58
あるファイルのiostreamを与えられるんだが、 そのファイルはユニコードで書かれている。 なのでiostreamをbasic_iostream<wchar_t>あたりに変換したいんだが なんか便利な方法ある? std::wstring str; std::getline(stream,str); みたいに使いたいわけなんだが。
最近ageるのがデフォなのか?
昔、「質問するときはage」って誰かに聞いたんだが 間違いだったか。 ならスマソ
467 :
デフォルトの名無しさん :2006/12/25(月) 23:18:27
「とにかくsageなきゃいけない」と思い込んでる頭のおかしな人が たまにいるんだよ。 ちなみに、そういう人に「なんでageちゃいけないのか」を訊くと、 なぜか回答らしい回答が無いかわりに人格攻撃とか始めるから注意な。
470 :
デフォルトの名無しさん :2006/12/26(火) 13:28:12
あげ
>>464 read でバイト列読んで、memcpy でもすれば?
それにしても、最初から wifstream を渡してもらえたら楽なのにねえ。
>>464 便利だけど簡単かどうかはわからない。
Boost.Iostreamsでなんとかするというのはどうだ?
>>464 ファイルの中身が Unicode (UTF-16と仮定)なら、2BYTEずつ読んで、
wstring に追加していけばいいんじゃない。楽な方法はないと思う。
wgetline( istream & i, wstring & str ) {
char wrk[2] = {0};
while( !!i.read( wrk, 2 ) ) {
wchar_t ch;
memcpy( ch, wrk, 2 );
if( ch == L'\n' ) break; // 超適当。
str += ch;
}
}
streambuf実装してwistreamでラップするとか
Boost.Iostreamsも結局やることはそれなんだよな。
WikipediaのSTLの項目で難解さのコード例があるけど、 remove_ifよりpartitionの方が効率がよかったりするの?
>>479 remove_if() は operator = () によるコピー、
partition() は swap() による移動を使う。
あとは中身によってどっちが効率いいか決まるだろう。
サンクス。把握した。
すみませんが、質問です。
テンプレート関数の宣言で、型名がやたらと長くなってしまう場合、typedef
などで短縮名を付けることはできないのでしょうか?
T::value_type ぐらいならまだしも、boost::range_value< S >::type ぐらい
長くなると、これを引数や戻り値に何度も書くのは、なかなか冗長です。
こういう宣言を、
//------------動くが、戻り値の型名が長い----------
template <typename S>
typename boost::range_value< S >::type
join5(S b, // 開始イテレータ
S e, // 終了イテレータ
typename boost::range_value< S >::type s // 区切り文字列
)
//------------↓は実際は動かない----------
template <typename S>
typedef boost::range_value< S >::type T;
T join5(S b, // 開始イテレータ
S e, // 終了イテレータ
typename boost::range_value< S >::type s // 区切り文字列
)
などと書きたいところなのですが。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndeepc/htm/deep08032000.asp しかしここを見ると、typedefのテンプレート化はできないようです。
483 :
482 :2007/01/09(火) 21:49:00
すみません、貼るコードを少し間違えました。 //------------↓は実際は動かない---------- template <typename S> typedef boost::range_value< S >::type T; T join5(S b, // 開始イテレータ S e, // 終了イテレータ T s // 区切り文字列 ) まあ、動かない擬似コードではありますが。
そこで前処理、#defineはどうでしょう。
Oeeeee
>>482 の記事は2000年のものなのですが、2007年の今も状況は変わっていない
ということなのでしょうか?Boostあたりで何か便利なものが生まれていない
かと思ったのですが。
>>484 C++なので、できたらマクロは使いたくないです。482の記事にもありますが、
予測を裏切る作用が多いので。
template<typename S> struct Hoge { typedef typename boost::range_value< S >::type T; }; template <typename S> Hoge<S>::T join5(S b, // 開始イテレータ S e, // 終了イテレータ Hoge<S>::T s // 区切り文字列 )
488 :
482 :2007/01/10(水) 01:15:48
>>487 ありがとうございます。さっそく試してみました。
GCCなどでは、Hoge<S>::T の前の typename は省略できません。すると、
typename boost::range_value< S >::type
↓
typename Hoge<S>::T
かなり短くなりますが、T 一文字まで短くはならないようです。
また、構造体Hogeには他の応用がほとんどないのに、グローバルな名前空間に
登録されてしまうのも、ちょっと残念な気がします。
書く以外にない むしろフルネームなのに相当短いぞ boost::range_library::metafunctions::range_value_of<S>::type とかじゃなくて良かっただろう
490 :
482 :2007/01/10(水) 17:12:23
>>489 おっしゃることはもっともですが、では実際にそういう型名の関数を宣言しな
ければならなかったら、どうしたら良いのでしょう?
関数じゃなくてクラスだったら、typename boost::range_value<S>::type 程
度の長さでも、誰もがすぐに内部でtypedefしてしまうと思うのです。
template <typename S>
class join11 {
typedef typename boost::range_value<S>::type T;
public:
T operator()(S b, // 開始イテレータ
S e, // 終了イテレータ
T s // 区切り文字列
)
{
T ss;
for (S i = b; i != e; ) {
ss += *i++;
if (i != e)
ss += s;
}
return ss;
}
};
だけどファンクタって、型変数指定が必須で、こういう用途には使いづらいですよね。
wcout << join11<vector<wstring>::iterator>()(v1.begin(), v1.end(), L"*") << endl;
書く以外に無い。
どうしてもイヤだったら
>>487 みたいなヘルパ書いて
適当なnamespaceに閉じ込めておけばよかろう。
>>490 それにレイヤーを被せると
template<template<class> class Join>
struct xjoin_
{
template<typename S, typename T>
typename Join<S>::T operator()(S b, S e, T s) const
{
return Join<S>()(b, e, s);
}
};
xjoin_<join11> const xjoin = {};
xjoin(v1.begin(), v1.end(), ..);
一般的に解決するのは難しい。が、
タイプを減らすように部分的にデザインすることはできる
493 :
482 :2007/01/10(水) 20:49:27
みなさん、ありがとうございます。
>>491 たしかに、それが現実的な気もします。
>>492 template<template<class> class Join>
恥ずかしながら、この記述が分かりませんでした。
テンプレートを引数に取るテンプレートなのでしょうか?
何か参考になるリンクを教えていただけませんか?
494 :
482 :2007/01/10(水) 21:06:10
495 :
デフォルトの名無しさん :2007/01/10(水) 21:06:56
class Test { public: int hoge(int x) { std::cout << x << std::endl; return x; } }; int main() { Test t; std::bind2nd(std::mem_fun_ref(&Test::hoge),100)(t); } Test::hoge が constメンバ関数でないのにコンパイルエラーにならないのはなぜ? cygwin gcc 3.4.4 です。
>>495 なんでコンパイルエラーになると思うの?
497 :
デフォルトの名無しさん :2007/01/10(水) 22:45:41
>>496 bind2nd の第一引数が const で Test::hoge が constメンバでないから
constになるのは、std::mem_fun_refの戻り値であるstd::mem_fun_ref_t<int, Test, int>のオブジェクト。
499 :
デフォルトの名無しさん :2007/01/10(水) 23:13:07
>>498 しかし std::bind1st(std::mem_fun_ref(&Test::hoge),t)(100)
ではコンパイルエラーになります。
Test::hoge を const メンバにすればエラーになりません。
500 :
482 :2007/01/10(水) 23:34:45
何度もすみません、
>>494 だけ分かりました。
このようにコンテナとその要素を設計すると、
要素のクラス<型変数> を
X::rebind<型変数>::allocator_type
という決まった形式で呼べる、ということです。
だから呼び出し側の形式を固定化、汎用化できる、ということです。
しかし、固定化はできますが、その固定の形式は全然自由でありません。
この実装だと、
呼び出される側は 要素のクラス<型変数>
呼び出す側はX::rebind<型変数>::allocator_type
この形式でしか扱えないのです。typedef の自由さとはかけ離れています。
しかもたいていの場合、呼び出し側は元の型名より長くなってしまいます。
まあそれ以前に「コンテナとその要素の組み合わせでしか使えない」
ので、今回の「関数に与える型名を短くしたい」という目的には全く適わない
のですが。
501 :
482 :2007/01/10(水) 23:36:42
>>492 については、私はテンプレートにうとくて分かりません。
もっと勉強して、考えてみます。
なんだマルチか。
stl::stringラップして sprintf書式でバッファサイズ気にしなくてよくてある程度高速なformat()を実装してる例ってないですか?
STLと関係ないな
サンクス
boost::format
質問です VC8ではエラーになるんですが、これは書式としてはあっているんでしょうか //STLコンテナと、データを入れて、データがコンテナにあるか調べる関数 template <template <typename T,class Allocator = allocator<T> > class STLC,typename U> bool has_data(STLC<U>&data,U&value){ STLC<U>::iterator it = find(data.begin(),data.end(),value); if(it!=data.end())return true; elsereturn false; }
Allocator = std::allocator<T>とtypename STLC<U>::iterator
>>511 ありがとうございます
あ、typenameないとマズいですね
ご指摘の部分と、findもstd::findになおしてコンパイルしてみましたが
エラーで動いてくれないようです
あれから試行錯誤の末、型チェックはコンパイラ任せで
とりあえずは目的の動作はしました
template <template <typename T> class STLC,typename U,typename R> bool has_data(STLC<U>&data,const R&value){
typename STLC<U>::iterator it = std::find(data.begin(),data.end(),value);
if(it!=data.end())return true;
elsereturn false;
}
もしエラーが文法の問題だったとするとちょっと悔しいなぁ
ちょっと疑問なんだけど > template <template <typename T> class STLC みたいな書き方初めて見たんだけど、どういう意味なの?
template <template <typename T> class STLC,typename U,typename R>
>>513 テンプレート・テンプレート・パラメータ
§8.2.3、C++ Templates
Template template parameters are placeholders for class templates.
They are declared much like class templates, but the keywords struct
and union cannot be used:
In the scope of their declaration, template template parameters are used
just like other class templates.
The parameters of template template parameters can have default
template arguments. These default arguments apply when the corresponding
parameters are not specified in uses of the template template parameter:
簡単に言うとクラステンプレートをテンプレートの引数に持てるという意味だな。
そしてそれにデフォルトの型を指定する事もできる、と。
僕も一つ質問していいですか? template <typename T, typename U> と書くのと template <typename T> template <typename U> と書くのでは、どういう風に意味が違ってくるのですか?
>>515 テンプレート・テンプレート・パラメータと言うのか。
勉強になった。
>>516 下は通常あり得ない書き方だろう。
あるとすれば、クラステンプレートのメンバ関数テンプレート、の実装部分くらい。
template <class T>
class hoge {
template <class U>
void fuga(U arg);
};
template<class T>
template<class U>
void hoge<T>::fuga<U>(U arg) { }
みたいな。
>>519 あ、なるほど、確かに説明の所にメンバテンプレートと
書いてありました。
わかりやすい説明ありがとうございます。
STLのsetやmapのメモリ構造って、ただの2分木なんですか? それともB木や2色木みたいなバランス調整される構造なんでしょうか?
実装に依るだろ。GCCのSTLは赤黒木みたいだけど
VCだとどうなんでしょうかね?
ビタミンC
わざとバランス悪くなりそうな要素を突っ込んでみたら?
ていうかソース見れよ STLならヘッダでいいし そうでなくともVC++にはC/C++ランタイムのソースついてるだろ
VC8のDinkumwareのヘッダを見てみたが、xtreeという名前の ヘッダに赤黒木の実装が使われているようだ。
SortedAssociativeContainer コンセプトが探索その他の操作に対する 複雑性保証として最悪で O(log N) を要求しているので, 必然的に何らかの balanced tree による実装が必然になります. さらに iterator を指定しての (木構造中のノードを指定しての) 削除に 最悪で O(1) の複雑性を要求するので, AVL tree もダメでしょうね. あまりデータ構造に詳しくないのであれですが, B-tree も要素削除後の再平衡化が O(1) では無理だったように記憶しています. もちろん,どちらのデータ構造も欠点に代わる利点を持っていますけれど. したがって,実装としてはおおよそにおいて赤黒木に落ち着くのではないかと思います. >527 VC7.1, VC8.0 の set, multiset, map, multimap の実装は赤黒木です.
皆さん検証乙です
>>528 上のほうの主張はほとんどすべて間違っている。
データ構造について再履修しよう。
まず
>最悪で O(log N) を要求しているので,
>必然的に何らかの balanced tree による実装が必然になります.
は嘘。balanced tree 以外にもこの条件を達成できる
データ構造は存在する。もちろん bst が最も普通ではあるが。
次に
>さらに iterator を指定しての (木構造中のノードを指定しての) 削除に
>最悪で O(1) の複雑性を要求するので,
は致命的な嘘。要求するのは amortized O(1)。amortized の意味を
確認せよ。最悪 O(1) の削除は赤黒木でも普通は達成しない。
そして
>AVL tree もダメでしょうね.
は二つの意味で嘘。
一つ目は、AVL 木の削除は amortized O(1) なので条件を満たす。
二つ目は余談だが、deamortized という手法で削除を O(1) で
実行できるAVL木 O(1) が構成できる。
>>529 こういうのは「検証」というんだろうか?
検証と言わずに正直に「頭の悪い私の代わりに考えて下さって どうもありがとうございます」とでも書けばいいのに。
>>530 >>最悪で O(log N) を要求しているので,
>>必然的に何らかの balanced tree による実装が必然になります.
>は嘘。balanced tree 以外にもこの条件を達成できる
>データ構造は存在する。もちろん bst が最も普通ではあるが。
は521へ対するレスとして「ただの2分木か,それとも branced tree か」という
暗黙の仮定をおいてレスを書いてしまってました.すいません.
それ以降指摘されたことに関しては完全に自分の非で,特に赤黒木に対しては
自分でもなんでこんなトンチンカンなこと書いたのか,恥ずかしい限りです.
528の内容については,完全に無視してやってください.本当にすいません.
猛省して,データ構造について勉強しなおしてきます.
計算結果がvectorで返ってくる計算の場合、 関数のreturnにvectorをもってくるとおかしくなるから 計算結果込みのオブジェクトにしちゃうんだけど、 何か間違ってる気がする。 return vector<...>しても問題ないような書き方できないでしょうか? struct do_and_result { vector<Data> return_data; template< typename T> operator()(T &t) { ... return_data.push_back(..) .. return_data.push_back(..) //return(return_data); // できない? } };
下記のコードで unary_function<T,T> のTを指定する方法ないでしょうか? struct obj:public unary_function< T,T //Tをここから指定できない.なおかつTはオブジェトを適用したときにわかる > { T operator()(T &t) { ... return t; } }; 使用例 std::vector<int> ar for_each(ar.begin(),ar.end(),obj()) std::vector<float> ar2 for_each(ar2.begin(),ar2.end(),obj()) unary_functionはbindを使うときに必要らしく Tを自動設定できないかと思いました
>>534 template< typename T>
vector<Data> operator()(T &t)ではないのか。
>>535 objもクラステンプレートにしてはだめなのか。
>>534 > 関数のreturnにvectorをもってくるとおかしくなるから
何がおかしくなるのか言ってみな。
>何がおかしくなるのか言ってみな。 決まっているじゃないか、>534の頭だよ。
頭が悪いのに無理して煽らなくても。
煽りは挨拶 そして最後は釣りだったことに
541 :
534 :2007/01/23(火) 13:43:28
vector<int> func( ) { vector<int> ar(20); return ar; } にすると、スコープを抜けるとarのメモリーが解放されてしまうらしく エラーになっておちる
そんなことはない。
それなんて糞コンパイラ?
できないのも、しようとするのも問題外だな。
545 :
534 :2007/01/23(火) 14:29:44
忘れてた. 巨大配列をコピーすると計算時間かかるので参照で返してました。 std::vector<int> & vec_out_fun() { std::vector<int> vec(10); std::fill(vec.begin(),vec.end(),1 ); return vec; } void vector_return_func_test() { std::vector<int> vec; vec = vec_out_fun(); std::cout << vec[3]; }
>>545 それは落ちるだろ
こうするとか
std::vector<int> & vec_out_fun(std::vector<int> & buf)
{
buf.resize(10);
std::fill(buf.begin(),buf.end(),1 );
return buf;
}
スマートポインタの類を使うとか
typedef std::auto_ptr<std::vector<int> > ApVec;
ApVec vec_out_fun()
{
ApVec vec(new std::vector<int>(10));
std::fill(vec->begin(),vec->end(),1 );
return vec;
}
忘れ方が初心者すぎる
やっぱり>538だったか。
NRVO効かないの?
ローカル変数のアドレスを返すアホ
>>545 はEffective C++なんかにも書いてある典型的な誤りって奴だぁな
STLでもC++でもなくてCレベルの誤りだな ポインタじゃなく参照になるとこういうところで気が抜けちゃうんだろうか?
553 :
534 :2007/01/23(火) 19:15:52
話題を最初の話に戻すけど ローカル変数をコピー(大きい配列の場合、したくない) なしに返すには、関数を関数オブジェクトにして、 計算結果を関数オブジェクトのメンバー変数においておく という方針は、いいのかどうか? 他にもっといい方法があるのか知りたい
STL的には関数をイテレータにするとか
上の方に出てた template <template <typename T> class U> は template <template <typename T> typename U> だとコンパイル通らないですね。 templateの中のclassとtypenameって同じことだと思っていましたが 多少異なるんでしょうか?
>>556 Uは実在の型でないといけないから、テンプレートパラメータではなく
クラス名を書かなければならない。だからtypenameではだめ。
>>556 通常、U は、クラスか構造体にしかならないから…らしい。
ほうほう、これはEffective C++の著者にも教えてあげたほうがいいんじゃねーの
入力を2つとる for_each transform がない。 自分で作るのもいいけどbindとかと組み合わせると不安 どこかに安定したのがないだろうか
transformには2入力版もあるぞ。
2つ入力が必要なfor_eachはtransformで代用?
boost::zip_iteratorとか
なんで未来にレスしてるんだろう… エスパー登場!?
つまんねえ反応だ
先頭の空白を除去しようと思っていくつか試したんだが eraseってこんなに遅いもん? //1つ目 str.replace(0,space_num,L""); //2つ目 wstring tmp = str.substr(0,str.size()-space_num); //3つ目 str.erase(str.begin(),str.begin()+space_num); 100万回小さなループで試した結果 1つ目:1.6秒ぐらい 2つ目:1.8秒ぐらい 3つ目:5.7秒ぐらい テストコード boost::timer t; t.restart(); for(int i=0;i<1000000;++i){std::wstring str(L"123456789"); str.replace(0,2,L"");} t.restart(); for(int i=0;i<1000000;++i){std::wstring str(L"123456789"); std::wstring tmp = str.substr(2,str.size()-2);} t.restart(); for(int i=0;i<1000000;++i){std::wstring str(L"123456789"); str.erase(str.begin(),str.begin()+2);}
>>568 std::stringはstd::vectorに似てerase()は遅いぞ。
class my_class { public: my_class(int i) : i(i) {} void print_ptr(ostream* os) { *os << i << endl; } void print_ref(ostream& os) { os << i << endl; } void plus_ptr(int* n) { i += *n; } void plus_ref(int n) { i += n; } int i; }; int main() { vector<my_class> v; for (int i=0; i<10; i++) v.push_back(my_class(i)); for_each (v.begin(), v.end(), bind2nd(mem_fun_ref(&my_class::print_ptr), &cout)); // ポインタ渡しはOK for_each (v.begin(), v.end(), bind2nd(mem_fun_ref(&my_class::print_ref), cout)); // ※リファレンス渡しはコンパイルエラー int i=5; for_each (v.begin(), v.end(), bind2nd(mem_fun_ref(&my_class::plus_ptr), &i)); // ポインタ渡しはOK for_each (v.begin(), v.end(), bind2nd(mem_fun_ref(&my_class::plus_ref), i)); // オブジェクトのコピーでもOK }
※のところでerror: forming reference to reference type `std::ostream&'と言われます。 リファレンスを引数に取るメンバ関数からmem_fun1_ref_tを生成することはできないのでしょうか。 for_eachをつかってコンテナの中身を任意のストリームに吐けるようにしたいのです。 ポインタ渡しを使えばやりたいことは実現できるんだけど、好みの問題でできればリファレンスで渡したいのです。 あと、グローバル関数のoperator<<の特定の特殊化バージョンのポインタを取得することはできるのでしょうか。 operator<< <ostream, const my_class> とかやっても error: no matching function for call to `bind1st(<unresolved overloaded function type>, std::ostream&)' と言われてしまいます。
>>571 リファレンスリファリンス問題だな。標準ライブラリの欠陥だよ。
boost::bindでも使いなせえ。
574 :
デフォルトの名無しさん :2007/02/03(土) 19:07:58
いつも一緒にいたかった。 隣で笑ってたかった。 boostは次々変わるのに STLは立ち止まったまま。
次々変わったら、何のためのSだよ
577 :
571 :2007/02/03(土) 20:53:51
>>573 なるほど自分ではいかんともしがたい問題なのですね。ありがとうございました。
しっぽ落とさないんだよな
>>573 あぁ、前に悩んであきらめたなぁ・・
boost::bindだと平気なの?
g++だとこんなメッセージ出るのかよ heboい俺にはVCから移行できる気がしない
583 :
580 :2007/02/05(月) 03:01:53
そのためにboostを導入ってのも気が引けるんだよなあ・・ binder2ndとbind2ndの第2引数を const _Ty& _Right → _Ty _Right 強引にこうしちゃうと動くようになったりするんだが、他のとこが動かなく なりそうだしなあ・・
TR1が使えるのならstd::tr1::bindはどうよ。
mapにはPerlのkeysに相当する機能ってありませんか? キーの一覧を取得したいんです。 イテレータ使ってループ回すしかないですか?
「取得」ねぇ・・・
あ、わからない人は反応しなくていいです。
あ、わかる人も反応しなくていいです。
589 :
585 :2007/02/05(月) 17:33:38
間抜けなことを聞いてしまった。タイピング数を減らせればどうでもよかった。今は反省している。 素直にイテレータ使ってmapを巡回させることにします。スレ汚しすみません。
select1st作ってtransformするとか
591 :
585 :2007/02/06(火) 10:16:30
サンクス。そういうの探してました。 だがしかし、VC++に標準で付いてるSTLで開発してるんで使えません。
>>591 transform なら VC++6.0 にもあるよ。
こんな感じか。[Generic Programmingより] ただしVCはselect1stを含んでいないのでコンパイルできない。 STLportをインストールする必要がある。 #include <iostream> #include <map> #include <algorithm> #include <iterator> #include <functional> int main() { std::map<int, double> m; m[1] = 0.3; m[47] = 0.8; m[33] = 0.1; std::transform(m.begin(), m.end(), std::ostream_iterator<int>(std::cout, " "), std::select1st<std::map<int, double>::value_type>()); std::cout << std::endl; }
すげー VCしか使ったことないからかselect1stしらなかったけど 当然2ndもあるんね すげー便利そう
std::unary_functionを継承して自分で作れるよ
template <class T, typename U> struct select1st : public std::unary_function<T, U> { const U& operator() (const T& x) const { return x.first; } }; template <class T, typename U> struct select2nd : public std::unary_function<T, U> { const U& operator() (const T& x) const { return x.second; } }; たったこれだけ
597 :
594 :2007/02/06(火) 11:29:51
自分用には似たようなの作ってはいたけど、STLportの実装もそれだけなのか これは横槍ながら感謝です
悪い 上の実装ではコンパイルが通らないようだ こっちを使ってください template <class T> struct select1st : public std::unary_function<T, typename T::first_type> { const typename T::first_type& operator() (const T& x) const { return x.first; } }; template <class T> struct select2nd : public std::unary_function<T, typename T::second_type> { const typename T::second_type& operator() (const T& x) const { return x.second; } };
599 :
585 :2007/02/06(火) 13:57:26
おー、これは感謝です。 select1st, select2ndのコードまで教えていただけるとは思いも寄りませんでした。 ありがとうございます。
STLの利点は「もし無くても自分で作れる」という点が大きいな。 だからboostでtupleなんかが活躍しているんだろうけど。
自分はVC++2005を使っているのですが STLPortっていうのはどこで確認できるんでしょうか。 boost1_33_1を入れて普通にIncludeフォルダlibフォルダを VC++2005に設定したらboostは使えてるんですが STLPortっていうのが気になります。 確認方法が、あるんでしょうか。 板違いかもしれませんが、どなたか分かる方が居れば 教えていただきたいです。
ググれよ
stlportそれは・・・・・・・・使わないんじゃないか?
604 :
デフォルトの名無しさん :2007/02/07(水) 21:19:09
GDBでコンテナやイテレータを探索したいんですが、どうすれば参照出来るでしょうか?ただツール落として使うのは不可です。 vectorは参照出来ましたが、listはさっぱり構造がわからずうまく行きません。と言うのも、GDBから演算子関数が呼び出せないんです。 使い易く別でシーケンスを出力する関数を用意するにもテンプレの実行時特化で弾かれます。 何か解決策は無いでしょうか?
605 :
デフォルトの名無しさん :2007/02/16(金) 19:30:23
stringの size_type find(const charT* s, size_type pos) const; のposにstring::nposを指定した時の戻り値って規格で決まっていないんですかね? g++とVC6では結果が違ったので
>>606 普通に考えると npos 以外返しようがないと思うんだが、
npos じゃない値が出てきたの?
>>607 string s = "abcdefbc";
printf("%d\n", s.find("bc", string::npos));
を試してg++3.4.4(cygwin)で1が返り、VC6では-1(npos)が返りました。
どうせVC6が、nposの実値である -1 でそのまま処理したんじゃねぇの?
あ、志村った。てか、珍しく逆だったか。
規格的には 0 が文字列の先頭(==*.begin())を指すインデックスとして使われるのに対し、 npos はその逆で文字列の末尾(==*.end())を指すインデックスとして使われていることを考えると VC6の挙動のほうが規格的には正しい。が、nposが指定された場合の挙動が明記はされとらんねぇ。
明記されてないなら未定義だろう
>>612 直接明記はされてないけど、仕様としては最大値扱いのnposが渡されただけの
話なんで、普通に行間を読めばVC6の挙動が規格通りだと思うんだけど、
はっきりと明記されてない限りは未定義扱いになるんだっけ?
rfind は検索開始位置にデフォルト値でnposが渡されるが、特にnposが渡された時の扱いは 明記されてないまま、nposが最大値扱いな説明がされているところを見ると、VC6の挙動が 規格通りの挙動ってことでいいんじゃないか? はっきり明記されていない限り未定義って ことだと、rfind で検索開始位置を指定しなかった場合の挙動も未定義ってことになるぞ。
規格には見つからなかったらnposを返すと書いてあった気がするが
616 :
615 :2007/02/18(日) 11:21:39
ん、そういう話じゃなかったな。
定義上 npos == -1 == std::numeric_limits<std::string::size_type>::max()
なんだから、見つかるはずがない(必ずnposを返す)という解釈が
正しいんじゃないかな?つまり
>>614 で。
ちなみにSTLport4.6.2では位置を返すが、5.0.2ではnposが返るようになってた。
見つからないときは npos が返る。 今回のは gcc のバグ。 いくらか調べてみると、やっぱり npos がどっかで signed に 突っ込まれてるみたい。 npos を小さくしながら試していくと、 npos / 2 を渡したところから npos が返るようになった。
・・・
619 :
606 :2007/02/18(日) 12:32:21
いろいろ試していただいた方、サンクスです。 findにnposを渡した時、 ・規格で特に明記されているわけではない。 ・明記されていないがnposは-1で最大値扱いされているので、nposを返すと考えるのが自然。 ・現実にはSTLの実装によって動作が変わるのでこういうコードは書かないほうが良い。 しかし今度はnposの規格が疑問になってきた。 nposの規格って 1.検索失敗時に返す値 2.符号なし整数の最大値 1は規格にあると思うけど2は規格にあるんですか? 2がもしないならrfindにnposを指定した場合も未定義なのかな 規格ってISOで買うしかないんですかね。。。
規格書に曰く、 static const size_type npos = 1;
>>619 size_type は符号無し整数で、符号無し整数に変換された -1 が
その型の最大値を取ることは規格から導くことができる。
なるほど。nposが規格で-1となっているなら rfindにnposを渡すと最後尾から検索開始することが保証されますね。 となるとやっぱりg++3.4.4のfindにnposを渡した時の動作は変だ。
>>619 C++標準ライブラリ(規格の17章から27章)の部分だけでいいなら
国際規格(ISO) C++ライブラリハンドブックを買う手もある。
eMuleで落とす手もある
>>619 英語のドラフトでよければダウンロードできるよ。
日本語でよければJIS X3014の画像PDFという手もある。
文字列に属さない位置(0〜文字列の長さの範囲にない位置) を検索開始位置にした場合は、未定義なんじゃないの? rfindについては、検索開始位置が未指定の場合は末尾からの検索を 行うというのが仕様で、大半の処理系はその仕様をdefault値をnposにする ことで実装しているだけだと思うが。
>>628 rfindのデフォルト値は規格でnposと決まっている。
>>628 条件が満たされない場合はnposを返すとある。
gcc3よりvc6のほうが規格に合致してるのは気に入らない なんとかしてgcc3の挙動が規格上問題ないという証拠を見つけたい
>>631 patch投げるほうがたぶん建設的やで。
634 :
デフォルトの名無しさん :2007/02/18(日) 22:01:49
g++2.95のstringでさらにおかしな動作発見。 size_type find(const charT* s, size_type pos, size_type n) const; でn = 0を指定 string s = "abcdefb"; printf("%d\n", s.find("bc", 2, 0)); を実行して、 g++2.95: 6 ←"b"を検索しちゃってる g++3.4 : 2 VC6 : 2 を返した。 g++2.95の結果はおかしいとして、 検索文字列の長さを0にした時は規格的にはどれが正しいんだろ? 検索開始インデックス or npos?
size_type find(const charT* s, size_type pos, size_type n) const; Returns: find(basic_string<charT,traits,Allocator>(s,n),pos). s.find( "", 2 );と同じ。空文字列は当然、先頭にマッチする
>>631 gccのbasic_stringまわりは糞だからなぁ。
>>631 VC6のじゃなくてDinkumwareのと言えばOK
おまえらそんなにVC++6が嫌いですか
>>638 俺はgccのほうが大嫌いだけど、なんていうかさぁ、ほら、
のびたの癖に生意気だぞ〜、みたいな?
2.95まだ使ってる奴いたのか。
VCでもgccでもいいけど、 VC6とgcc2.95は早く滅びてくれるとみんな幸せになれると思うんだ…。
C言語新生児な俺はもvc6もgcc2.95も触ったことないけど、vc6は噂に聞いてる gcc2.95も似たようなものなのけ?
時期的にはだいたい同じじゃなかったかな そういやgcc2の終わりごろってegccとかforkしてた暗黒時代だった希ガス
ググってみると、 >途中からCygnus社(後Red Hatに吸収)が中心となってEGCSプロジェクトと称して >新しいGCCの開発に着手し,現在ではEGCSプロジェクトが正式なGCC開発元となっています。 と出てきた。gcc2.95は今のgccの先祖じゃないみたい。
どっちも下手に広まっちゃったから なかなかしがらみが消えないのが問題なんだよな。
2.95は結構珍しいと思う
Visual C++ 7.1 and higher GNU C++ 3.2 and higher Intel for Linux 8.1 and higher Intel for Windows 8.1 and higher tru64cxx 65 and higher QNX qcc 3.3 and higher MinGW 3.4 and higher Metrowerks CodeWarrior 9.4 and higher たぶんこれら以外はC++コンパイラではない Turbo C++は詐欺な気がする
現行規格からの逸脱が激しい、ぐらいにしたほうがいいと思うよ
ARMには準拠していると言える水準のものもあるわけだし。
2.96の挙動不審さは異常
2.95.2とか今でも結構使われてるな
ちょっと質問です。 std::string::iterator を返す関数があるんですが、 例えばエラーが出たときに、ポインタで言う NULL を返したいのです。 イテレータに、NULL に変わる何かはないでしょうか? 位置を int を値で返す関数には、std::string::npos があるけど…
例 外 で や れ
あほくさいけど、 ヌルを意味するダミーのstringを作ってそいつへのイテレータを返す 関数の返り値とダミーのstringを比較する。
直接は無さそうですか… その辺りの方法も検討して見ます、ありがとうございます。
>>652 std::find()みたいに、単にend()を返すのではまずいの?
どうして .end() じゃダメなんだ?
>>656 その関数は、end を知らないので…
あー、引数で being と end を渡しておく方が自然ですね…
ありがとうございます
iterator を返すならend()も当然知ってるんじゃないの??
660 :
654 :2007/03/18(日) 21:58:48
チェック関数は当然begin/endを知ってるけれど、呼び出し元はbegin/endを知らない あるいはどの文字列のendを返してくるか判らない。 呼び出し元はイテレータ経由で文字列を操作するけど、 イテレータは動かさないのでendは知らなくていい。 という状況を想像した。
ちょうどstringの話題が・・・ std::string を戻り値とする関数って、当たり前だけど string の中身がまるまるコピーされるわけだから そのぶん処理時間的にコストになるわけですよね? 何気なくstd::stringを返却する関数を作ってた自分に気がついてハッとした
>>661 いや、大抵はstd::stringの中身には文字列そのものは含まれてないわけだが。
なんだっけ? 戻り値のコピーしないようにする最適化とかあったよね?
>>662 リファレンスカウントを使っているタイプのstd::stringじゃなきゃ中身の文字列もコピーされるぞ。
んでもって、今はリファレンスカウントを使わないタイプのstd::stringが主流だぞ。
そこでMove semanticsと右辺値参照ですよ
たしか、オブジェクト返値にたいしてGCCがスゴイ拡張してなかったっけ?
>>666 手動で戻り値最適化ができる、べつにすごいわけでもない拡張があったけど、
ちょっと前のバージョンで削除されたような覚えがある。
確か中ではポインタだけコピーして、非const操作が入ったときにコピーをつくる (内製Copy-On-Write)なんてことをしていたオカン。
質問です。 mapってmergeできないんですか?
同じキーがあった場合どうするの?
671 :
デフォルトの名無しさん :2007/03/28(水) 19:51:17
内部クラスをファンクタとして使うのは駄目なのでしょうか? コンパイルエラーになってしまうのですが。
672 :
デフォルトの名無しさん :2007/03/28(水) 20:00:24
言い方がまずかったかもしれませんので訂正します。 「関数の内部」で定義したクラスをファンクタとして使うのは 駄目なのでしょうか? コンパイルエラーになってしまうのですが。
関数内でコードを生成するような試みは、だいたいISOが禁止してる。 例外は式テンプレートだけといっても良かったはず。
関数内ローカルクラスのメンバとして定義すれば ローカル関数として使えるんじゃなかったっけ まぁ良い方法とはいえないけど…
int main(int argc, char* argv[]) { struct FuncA { int operator ()(const char* p) const { return p[0]; } }; struct FuncB { int operator ()() const { return 0; } }; return (argc > 1) ? FuncA()(argv[1]) : FuncB()(); }
676 :
デフォルトの名無しさん :2007/03/28(水) 20:54:16
>>675 すみません。
ユーザが勝手に使う分には問題ないのですけどfor_eachや
accumulate等の引数として与えた場合が駄目なのです。
STL板だったので伝わるかと思ったのですが言葉足らずでし
た。
for_eachなんかで使うときは近くでファンクタを定義した
方がわかり良いと思ったので関数内でファンクタを定義でき
ないかなあと思ったわけです。
ローカルクラスは、その関数内でしか使えない。 テンプレート引数として渡す行為は、これに反して 外に漏れることになるから、できない。
int main(){ std::vector<int> a; a.push_back(5); a.push_back(6); struct Opr{ static void op(int i){ printf("%d\n",i);} }; std::for_each( a.begin(), a.end(), &Opr::op ); } あれ。通った。
679 :
デフォルトの名無しさん :2007/03/28(水) 21:06:51
>>677 ありがとうございます。仕様のようですね。
ローカルクラスという言葉を知っていたらネットで見つかったのにと
思います。実際見つかりました。
>>674 さんありがとうございました。
面倒かけました皆様。
つぎはぎだらけの糞ライブラリ集だなこりゃ
Google はそんなのより Firefox 2.0 対応のツールバーを作れよ
誰か助けて。。。 pthread_createでスレッドを生成して そのスレッドの中で指定秒数SLEEPしてから あるコールバック関数を呼ぶみたいな タイマー処理するようなクラスを作って コールバック関数で std:string test = ""; test = test + "1"; stringを使用して文字編集を行った後 再度↑のクラスの処理を実行して ぐるぐる処理するような事したんですけど 4096回目のコールバック関数の中でアボートするんですけど 原因なんでしょ? ↓しかも落ちる箇所ここ test = test + "1";
よくわからないが、 Thread->Timer->Callback->TImer->Callback...という呼び出し履歴になっていて、 単純にスタックが溢れた、という話ではないのか?
>>683 全ソースが目の前にある君を差し置いて
たったそんだけの情報でデバッグできるほどのエスパーは
ここにはいませんよ。
つか、せめて test += "1" くらいにしとこうや。
>>683 >std:string test = "";
>test = test + "1";
ホントにこんなシンプルなコード?
他のスレッドからもその変数をいじってるんじゃない?
>std:string std::stringのtypoだよな? つか、このコード、これだけだと std::string test = "1"; と同じなのだが。
>>686-687 std::string test = "";
// 他スレッドからバリバリ呼ばれるよ
void hoge()
{
test = test + "1";
}
というイヤな予感。
STLってそのレベルのthread safetyって全く保障してないんだっけ。 実装依存?
素人はスレッドに手を出したらアカンで。
>>689 こんな低レベルの処理をいちいちスレッドセーフにしてたら
遅くて使い物にならない(使いたくない代物になる)と思うよ。
>>689 そもそも標準C++の範囲にスレッドという概念がないから保証とかはまったくない
>>691 java.utilのCollectionsだと、デフォは同期制御なしで、
同期制御つきのラッパーを別途提供という形だよな。
そういうのあると便利じゃないかと思うんだけど。
std::stringやSTLコンテナクラスは継承を前提にしていないから同じ手法は
使えないが、その辺はテンプレートパラメタによるポリシーの指定などで
どうにかできんものか。
>>693 できる、けどやってない。そういうポリシーなんだと思うよ。よく知らないけど。
>>695 そのスレ落ちそうなのでこっちで質問ですが、boost::spiritの練習で
URLをパースしようとしてます。
uri = scheme >> ': >> !("//" >> netloc) >> path >> !('?' >> qstring) >> !('#' >> fragment);
netloc = (
(username >> !(':' >> password) >> '@' >> host) |
(host)[bind(&uriparse::clear_auth, &me, _1, _2)]
) >> !(':' >> port);
scheme = (+(alnum_p|'-'|'_'))[assign(me.data.scheme)];
username = (+(alnum_p|'-'|'_'|'.'))[assign(me.data.username)];
password = (*(graph_p - '@'))[assign(me.data.password)];
(改行多いといわれたので以下の同様の行は省略)
こんなコードなんですが、動くものの気に入らない点があって、
http://hogehoge:9999 というURLを処理すると上の定義では
http://username:password@host:port/ http://host:port/ の区別が先に行くまでできないため、me.data.username/passwordまで
セットされてしまうのです。
やむなくバックトラックして戻ってきたところでクリア関数を呼んでるのですが、
もっとエレガントに後処理なしで一発で処理できるような定義にできないでしょうか?
落ちそうだからってこっちのスレ汚すな。 クロージャ使ってnetlocのセマンティックアクションでmeとやらに入れろ。
>>697 すみません、移動します。(ただ、netlocでだとどっちにマッチしたか判らないのでは)
699 :
デフォルトの名無しさん :2007/04/15(日) 10:43:37
valarrayでの演算でsseを使ってくれるよう指示するにはどうしたらよいのでしょうか? OSはFC5、コンパイラはgcc4.0です。
valarrayに限らず、-msseでsseを使った最適化をしてくれる可能性があるわけだが。 どうしてもvalarrayでsseを使いたいなら自分で実装するしかナインジャマイカ。
701 :
デフォルトの名無しさん :2007/04/28(土) 21:56:05
反復子は、それがvectorコンテナの何番目の要素を指してるかを知るには、先頭から 順番に移動して調べるしか方法がないと思ってるけど、その通りか。
機械翻訳みたいな文章の質問だな
advance
>>701 その反復子がstd::vectorのあるインスタンスの反復子であると知っている場合、
std::vectorの反復子は、ランダムアクセスイテレータなので、減算演算子が使用可能。
std::vector<int> v(8);
std::vector<int>::iterator it = v.begin() + 5;
このときit - v.begin() == 5となる。
distance()
distanceとかadvanceはランダムアクセスイテレータに対しては減算で処理してくれるの?
そのためにiterator_tagがあるんだろ
709 :
デフォルトの名無しさん :2007/05/20(日) 09:23:11
vectorではsseは使えないのでしょうか? 配列からvectorに変えたらdata type mixedで並列化されなくなってしまいました。 valarrayでは大丈夫なのですが
使えるよ。
物によるとしか言いようが無いな
ポリシーってインターフェースにする様なのをテンプレートで書いて溜めておけばいいんすか?
好きにすれば良いよ。
ポリシーが含むのはインタフェースに限らないよ
>>714 例えばどんな物がポリシーに出来ますん?
馬鹿だから応用の仕方がイマイチわからに。
スレッドに関するポリシーとか?
>>716 ああそっか。本にもスレッドのポリシー書いてありましたわ。
なるほど。
vector<vector<T> > vec( m, n ); のような2次元配列のコンテナにアルゴリズムを適用するとき、 forを使わずに書く方法はありますか? forを使うと、可読性が落ちるような気がするので。 たとえば、 for_each( vec.begin(), vec.end(), ... ); で、vecのすべての要素に0を代入したりとか。 forで書くと、 for( int i=0; i < vec.size(); ++i ) { for( int j=0; j < vec[i].size(); ++j ) { vec[i][j] = 0; } } のような感じのを書きたいんですが。 なければあきらめてforで書きます。
>>718 #include <iostream>
#include <vector>
#include <algorithm>
#include <boost/foreach.hpp>
int main()
{
std::vector<std::vector<int> > vec(10, std::vector<int>(10));
BOOST_FOREACH(std::vector<int>& row, vec)
BOOST_FOREACH(int& i, row)
i = 999;
BOOST_FOREACH(std::vector<int>& row, vec)
BOOST_FOREACH(int& i, row)
std::cout << i << ' ';
}
やっぱboostってすげーや
>>719 レスありがとうございます。
それでやってみます。
>>718 boostを使わなくても、std::fillする関数用意してstd::for_eachで回せばいいんでない?
>>722 いいけどsize()で要素数を調べないといけないよ
724 :
722 :2007/05/26(土) 04:42:20
あーなるほど、意外に面倒そうやね。
結局こんな汚いコードになってしまう。 template <class T> struct Fill { void operator()(std::vector<T>& v) { std::fill(v.begin(), v.end(), 0); } }; int main() { std::vector<std::vector<int> > vec(10, std::vector<int>(10)); std::for_each(vec.begin(), vec.end(), Fill<int>()); }
それを書くならこうだろ。 #include <iostream> #include <vector> #include <algorithm> template <class T> struct Fill { Fill(T i) : j(i) {} void operator()(std::vector<T>& v) { std::fill(v.begin(), v.end(), j); } private: T j; }; int main() { std::vector<std::vector<int> > vec(10000, std::vector<int>(18000)); std::for_each(vec.begin(), vec.end(), Fill<int>(0)); }
boost::ublas使ったほうが楽だな。
boostにublasあったのか。cublasのラッパ作る参考にさせてもらおう。
boost::bindかlambda使ってもできそうだな
つーかlambda使いたくなる典型的なパターンじゃね この程度の処理にわざわざ関数オブジェクト定義したくねぇよ というパターン
boost::bindとかboost::lambda使って簡潔に書くとどういう風になるの?
using namespace boost::lambda; using boost::begin; using boost::end; std::vector<std::vector<int> > vv; std::for_each(vv.begin(), vv.end(), bind(fill(), bind(begin, _1), bind(end, _1), constant(0)));
boost::begin, boost::endって何っ素か
_1が曖昧だとか怒られます #include <vector> #include <algorithm> #include <boost\bind.hpp> #include <boost\range.hpp> #include <boost\lambda\lambda.hpp> int main() { using namespace boost::lambda; using boost::bind; using boost::begin; using boost::end; std::vector<std::vector<int> > vv(10); std::for_each( vv.begin(), vv.end(), boost::bind( std::fill ,bind(boost::begin, _1) ,bind(boost::end, _1) ,constant(0) ) ); return 0 }
>>736 たぶんbindが<boost/bind.hpp>のboost::bindと
<boost/lambda/bind.hpp>のboost::lambda::bindの2つあるせい。
名前空間を指定してやらないといけない。
でもそれを直したところで、うちのVC++8ではコンパイルできなかったけどな。
MiGW(gcc3.4.2)でも通らねーよヽ(`Д´)ノウワァァァン
多重定義されている関数は、bindする時点でどれを使うか決めないといけないのだが、 それではどれを選んでいいのかわからず曖昧だからというのがコンパイルできない理由のはず。 これはコンパイルできた。しかし、static_castを外すとコンパイルエラーになる。 #include <vector> #include <boost/bind.hpp> #include <boost/range.hpp> #include <boost/ref.hpp> #include <boost/range_ex/algorithm.hpp> int main() { std::vector<std::vector<int> > vv(10); boost::for_each( vv, boost::bind( static_cast<void (*)(std::vector<int>&, const int&)>(boost::fill), _1, boost::cref(0))); return 0; }
range_exなんてあったっけと思ったらsandboxか… でもわざわざ面倒な書式にしてあるstatic_castや、 非標準のboost使う羽目になるから、素直にublasやFOREACHマクロ使った方がいいって事なのかな lambdaが有効に使えると思ってたが残念な結果だぜ
テンプレートとグローバル関数の多重定義は相性最悪だからな
結局boost::lambdaって使えねーよな 意味不明のコンパイルエラーを 追っている時間が無駄
真のc++wizardはコンパイルエラーなど出さない
真のC++使いはコンパイル時に無限ループさせちゃいます
残念ながらテンプレートの展開には深さの制限がかかっているから 無限ループにはできない
ブラフマーの塔が完成するまで終わらないなら、 事実上無限ループと変わらないとおもうけど
一応「最低」17回は再帰的にインスタンス化することが保証されてるだけで 無限にループする処理系がないということではない気がする
boostやその他のテンプレートライブラリで意味不明なエラーが出るのはそれ超えてネストされてるから?
7600 億回のインスタンス化ワロタ
仏教的な数値だ
7600億回だとランタイムでも無理
>>752 これは寧ろ、(コンパイラの)ランタイムと考えるべきだと思う。
>>740 ちなみに、ublasだとどう書くんだ?
using namespace boost::numeric::ublas; matrix<T> mat(m,n); std::fill(mat.data().begin(),mat.data().end(),T(0));
それが一番簡単だな。 今までの議論は何だったんだ
なぜかmatの中身が未初期化になっちまいますが… #include <boost/numeric/ublas/matrix.hpp> #include <algorithm> #include <iostream> static void out(int i) { std::cout << i << ' '; } int main() { using boost::numeric::ublas::matrix; int m=2, n=2; matrix<int> mat(m,n); std::fill(mat.data().begin(), mat.data().begin(), int(0)); std::for_each(mat.data().begin(), mat.data().end(), out); return 0; }
これは突っ込むところ?それとも放置してあげるべき?
begin()からbegin()に適用してどうする
basic_streambufにpubseekposとかあるのになんでistreambuf_iteratorはinput iteratorですか?
シーク不可能なストリームもあるからだと思う
ハードディスクなんかはseekg()とseekp()を別々に設計できるのに 実際は同じだしな
シーク不可能なストリームとシーク可能なストリームをクラスで分ける仕様にしなかった禿は低脳
>>763 下部構造を忠実に反映してるだけだろう。
端末やパイプに対してもfseek()は呼べる。実際にはシークできなくとも。
そして、ディスクリプタ(や何か)がシーク可能かどうかを調べる
移植性の高い方法も存在しない。
要は、「飛べる。が、実際に飛ぼうとするとエラーになる」状態なわけで、
現状はそれを忠実に反映したデザイン。
クラスを分けるということは「飛べない」ようにすること。
キューのサイズを固定した片方向キューを作りたいのですが、どのようにすればよいのでしょうか?
>>765 キューのサイズを固定した片方向キューを作る
767 :
デフォルトの名無しさん :2007/06/07(木) 11:30:00
std::queueを包含したキュークラスを作り 必要なインターフェースの為の窓口クラスを作って終了
バグが出てきて再開
包含+公開用インターフェースってのは1からつくるするよりはバグ少ないと思うけど やっぱそういうことせずにそのまま使えってことですか?
ケースバイケース
リングバッファつくればいいんとちがう?
ものすごく初歩的な質問で恐縮ですが・・・ Ctrl + Zを入力するまで無限ループするにはどうしたらよいでしょうか? while( cin.get() != EOF ) {
774 :
773 :2007/06/15(金) 20:53:06
すいません、間違って書きこんでしまいました。 while( cin.get() != EOF ) { } にすると、いちいち何か入力しなければ、ループが回らないのです。 ループを回しつつ、EOF待ちにするにはどのようにかけばよいでしょうか?
マルチプロセスかマルチスレッド
kbhitみたいなのが標準にあればいいんだけどね
シグナルハンドラじゃないの?
778 :
デフォルトの名無しさん :2007/06/16(土) 01:15:51
fcntl と O_NONBLOCK でぐぐレ
ベクターの要素を参照するとき v[i]とv.at(i)どっち使ってますか?
atと[]の違い知らないの?
知ってます iが正しい位置さしてるとわかってる場合は[]でいいですよね、、、
なんだ、答え出たじゃん
うーん、上司のソースがすべてatで書かれてたので、 何か裏の理由でもあるのかな、、、と思いまして。。。 すみません。at て[]よりも遅いような気がするんですが。。。
そもそもstd::vectorならiteratorを使うから積極的にat()や[]を使う局面は少ないような。 ま、at()の方が速いってことはないのは間違いないな。
atのところはちゃんと例外キャッチして使ってます? 例外キャッチしないで使ってるなら、上司が無知なだけ
つーかその上司に裏の理由とやらを訊けよ
787 :
デフォルトの名無しさん :2007/06/19(火) 21:05:42
クラスのlistとイテレータについての質問ですが、 class Hoge{ int a; } というクラスがあって、そのリストstd::list<Hoge>を作って、 そのイテレータstd::list<Hoge>::iterator it を用意しました。 このときメンバaにアクセスするとき、 it->a と (*it).a は同じですか? (*it).aに代入してもaは変更されますか?
YES
>>784 そうか?
value_type operator [] ( const size_t idx )
{
return at( idx );
}
だったら、上司にあやまれ。
>>785 std::vector::at(..) ってthrowするの?
java.util.Vectorと勘違いしてないか?
at は範囲チェックすることが保証されてるから速度は [ ] ≧ at 。
throwするね。
じゃないと[]と使い分ける意味がないな
そこまで言うなよ・・
>>794 ポインタを使う時に [ ] が少し使いにくいという点があるから、
範囲チェック無かったとしても使い道がないわけでもないかな。
VC8.0+STLport5.1.3を使ってICU3.6をコンパイルしてるのですが、全くうまくいきません。なにかご教授願いたいです。
まず、服を脱ぎます。
>>789 そんな仕様と違う実装なわけねーだろ低脳が。
それはその通りなんだが、なんで朝っぱらからそんな怒ってるんだ?
>>802 家族に愛想尽かされたんだ、察してやれよ。
おお!愛想を尽かされるとはなんてかわいそうな802! 802よ!俺で良かったらいつでも相談に乗るよ! 結婚したこと無いけど。
806 :
デフォルトの名無しさん :2007/06/21(木) 13:26:12
レンジチェックしてないのはatの方だと思ってた。 それで例外投げられちゃうのか…
[]演算子はコンテナ以外にもよく使われるから例外投げたら解りにくいだろ
808 :
デフォルトの名無しさん :2007/06/21(木) 18:24:26
例外を投げるのは[]なんだけど? ともったら、substrだった
809 :
デフォルトの名無しさん :2007/06/23(土) 15:02:15
質問させてください。 mapでは [] 演算子を使って値を変更できましたが [] 演算子の使用が出来ない multimapで値の変更をする方法が分かりません。 ご存知の方いらっしゃいますか?
>>809 find()→erase()→insert()の順で入れ直す。
というのはstd::multimapは同じキーで値が異なる要素が存在する
可能性があるので、当該のキーを削除してから改めて挿入しなおさ
ないと正しく処理できないから。
あ、悪い、find_if()だった。 なお、erase()した場合はその反復子が無効になるため、insert()した後 改めてfind_if()して、該当する要素が見つからなくなるまでループする 必要がある。
812 :
デフォルトの名無しさん :2007/06/23(土) 15:19:47
>>810-811 なるほど。重複の可能性から1度きりの入れ直しだけでは不十分なんですね。
ありがとうございます。参考になりました。
>>810-811 出し入れが必要なのは set, multiset じゃないの?
map, multimap なら fin(), find_if() して出てきたイテレータの
second をいじれば値の変更はできるはず。
>>813 試してみたところ、イテレータの second に代入して変更できました。
#include <windows.h> #pragma warning ( disable: 4786 ) #include <iostream> #include <string> #include <vector> using namespace std; vector<string> gv_szFileName; void sub( char *filename ) { WIN32_FIND_DATA data; HANDLE h; h = FindFirstFile( filename, &data ); gv_szFileName.push_back( data.cFileName ); if( h != NULL ) { while( FindNextFile(h, &data) ){ gv_szFileName.push_back( data.cFileName ); } } FindClose(h); }
816 :
デフォルトの名無しさん :2007/06/23(土) 16:20:06
void sub2() { int i; for( i=0; i<gv_szFileName.size(); i++ ) cout << gv_szFileName.at(i) << endl; // ここでエラーが発生する } void main() { sub( "c:\\*" ); sub2(); } 俺のノートPCだとアクセス違反が発生する なぜだろう・・・
>>815-816 FindFirstFile() が失敗してんじゃね?
エラーチェックは INVALID_HANDLE_VALUE で。
失敗したときは FindClose() しない。
vector の問題だと思うんなら Windows API 使わずに
問題を再現させるんだな。
gv_szFileName.size() が 15 の値を返すのに for( i=0; gv_szFileName.size(); i++ ) のループで i == 15 の時ループに入っている vector の問題かな 再インストールするしかないかのかな
for( i=0; gv_szFileName.size(); i++ )だって? i < gv_szFileName.size();ではないのか
>>811 連想コンテナであるstd::mapに
std::find_ifを使うのは
効率が悪いからナンセンスと思っていたが
別に何か俺の知らない理由があるのか?
lower_boundとupper_boundでfind_ifするんかねぇ?
823 :
デフォルトの名無しさん :2007/06/23(土) 21:02:11
std::vector<int> v(10); で確保した vector の中身の先頭へのポインタって、 C のサブルーチンに &v[0] で渡してもおk? vector<int> の内部表現ってメモリ上でも連続している ってことが保証されているんだっけ? どうしても C で書かれたライブラリに渡さなければならないことがあって・・・
825 :
デフォルトの名無しさん :2007/06/23(土) 21:15:06
>>824 THX
やっぱ普段から C++ つかってても、STL の仕様とかちゃんと
読まなきゃだめだね。STL に関しては特に
「ほかのソースでこれやってるからできるんだろうな」
って感じで使ってきたから、だめだめだわ、俺。
まあ、STLの中の文字列とか、リストデータで繋がってるから そのままポインタだけ引っ張り出しても、何の事かワケわかめだろうな。 しかも¥0で終端なんてしてないし。 ちゃんとC用の文字列として取り出せる方法があったはず。
何を言ってるのかわからん std::stringの実装のハナシ? c_str()?
830 :
デフォルトの名無しさん :2007/06/25(月) 02:39:28
質問です。 汎用のコンテナ用出力関数を作ろうと思い、コンテナを引数に受けるテンプレート関数を作りました。 ここまではOKなんですが、コンテナのイテレータを作ろうとするとエラーになってしまいます。 何か特別な方法とかがあるのでしょうか? template <typename X> void output(const X& rContainer){ X::iterator iter; // ここでコンパイルエラー }
エラーメッセージを貼ってくれないので分からんが typename X::iterator iter; とか
>>831-832 おおお…God。
無事にコンパイル通りました。ありがとうございました。
FindFirstFileが失敗した時はNULLじゃなくてINVALID_HANDLE_VALUEな。 std::以前の問題だ
この typename って、 昔 VC++ でエラーになって 何じゃそりゃと思った記憶があるんだけど、 今でもそうなの?
>>835 VC6.0は1998年以前に出ているから偽標準コンパイラ
2003→2005と進むにつれて準拠度は大幅に上がっている
特に2003ではほとんど標準に準拠した
2002 でも確かエラーだったような。 クラステンプレートのメンバ関数テンプレートの実装も 未だにクラステンプレート宣言内じゃないとできなかったり、 満を持して登場と思ったのにこりゃひどいと思った記憶が。 static const int メンバ定数の直接初期化には対応してたけど。 この typename は 2003 からは対応してるっつーことでいいの?
多分そう それに2003は驚く事にtypenameが本来必要な場所で省略できたりした まあコンパイラを賢くすればできない事もないらしいがエラー吐いてくれない のには時々困った C++0xでこの辺は煮詰められる模様
俺、未だにこの typename は TYPENAME マクロに置き換えてるな。 環境によって有無を切り替えられるように。
840 :
デフォルトの名無しさん :2007/06/25(月) 13:54:21
VC++ 2005 マンセー ただ、IDEが時々固まっちゃったりするのは Vista のせいか・・・ XP マンセー
boost::lambdaとかバリバリ使えるからな 2005で大分賢くなった気がする
boost 1.34 も問題なくコンパイルできるしな。
mingw g++3.4.2を使っています。 numerical_limits<double>::min()よりも小さい値をoperator >>で読めないものでしょうか? 数値解析した結果をcout << や printf等で出力すると、e-320等とIEEE754倍精度の範囲外の出力が出ることがあります。 実際、 cout << numeric_limits<double>::min()/100; 等とすると、なぜか正常な数値が出てきます。 ところが、このようなIEEE754倍精度を越えた数値を、operator >> で doubleの変数に読みこもうとするとエラーが出ます。 ストリームも先に進んでいないので、エラーが出たら0にする、みたいな手法も通じません。 マニピュレータか何かでこれを回避できないでしょうか? 今の所、scanf (これだとなぜか読める)で読み込んでますが。。。
844 :
843 :2007/06/28(木) 13:42:10
scanfで読めるというのも間違いでした。 読めませんね。 怪しい数値を出力はするくせに読めないとは。。。とほほ.
>>843 計算途中の値はメモリ上にあるというのはわかるよな?
現在のいくつかの処理系では浮動小数点数はメモリ上で拡張倍精度浮動小数として計算される。
拡張倍精度浮動小数は、当然double(倍精度)よりも精度は高い。
だからこの場合のようにdoubleの範囲外の出力がなされることもあるわけだ。
ただしこれはメモリ上限定の話で、変数に格納される場合は当然ながらdouble値として格納される。
ゆえに出力がdoubleの範囲外になることはあっても、その精度のまま変数に格納は出来ないわけだ。
そこらへんのことは、詳しくはここに書いてある。
http://hw001.gate01.com/eggplant/tcf/cpp/floatprecision.html
メモリ上じゃなくてレジスタ上だろ。
848 :
843 :2007/06/29(金) 01:59:00
とりあえずlong doubleでいったん読み込んでからdouble変数にキャストしたらいけた。 843の例はlong doubleとして出力されたみたい。 しかし謎なのは、最初につまづいたデータはdouble配列をsprintfで書き出した物なんだよね。 レジスタで拡張というわけでもないのに、それにe-320なんてのが混じってる。 8087系のコプロが80bitなのは知ってるが、指数部の桁は64bitと一緒だから、仮にそうであってもこういう値はでないはずなのだが…
>>848 処理系にもよるが long double と double の精度は同じだったと思うが。
>>851 それを書くなら「処理系にもよるがlong doubleとdoubleの精度は違うと思うが。」
だろ。同じなのはMS系のC/C++だけじゃないの?Borlandもgccも違うぞ。
どっちも微妙な表現だな。 処理系によって、long double と double の精度は 同じだったり違ったりする、だな。
854 :
843 :2007/07/04(水) 13:23:30
つーか、変な数が出てくる原因はともかく、 取扱可能範囲を越えた数値を入力した際に簡単にリカバリーしたい。 アンダーフローかオーバーフローかとかエラーの内容がわかって、 その後簡単にトークンを読み捨てられたらいいわけで。
読み込みに失敗したら cin.fail() が真になるから、 そこで cin.clear(); cin >> str; で文字列1つ読み捨てれば? 1.0e-350-1.0e+20 とかの時に全部読み捨てられるのが困るなら もうちょっと凝る必要があるけど。 double の精度より小さい値が出るのは、 2進ダンプしてみたところ、 どうも Intel 系 CPU は指数部が 0 の場合も可能になってるからっぽいな。
いや、Intel 系 CPU とかの話じゃないな。 非正規化数ってやつみたいだ。 ちゃんとした IEEE の仕様みたい。
857 :
843 :2007/07/04(水) 15:50:06
>>855 , 856
なるほどね。
実際の演算、出力には非正規化数として小さい値を認めていると。
にも関らず、入力ではハネる…首尾一貫してねーなw。
入力でも非正規化数を扱えるようにしておくべきだろ、常識的に考えて...
GCC だと非正規化数も入力できる。 どこまで入力できるようにするかは、処理系依存っぽい。
859 :
843 :2007/07/04(水) 15:57:06
migwのgccでやってハネられてるんだけど...
じゃあ、同じ GCC でも環境によって違うんだろう。
boost::serialization でも quiet NaN を出力できるのに 入力はできなくて例外が発生する。不便だなぁ、と思う。
>>859 mingw だと Windows の libc を使うだろ
863 :
849 :2007/07/05(木) 23:53:51
え!?俺のせい!?
任意の要素のイテレータを得るのに、例えばvc8のvectorだったら iterator itat(size_type t) { return (iterator(_Myfirst + t, this)); } とか一々書いているんですが、実はこんな事しなくても済む方法ってありますか?
>>865 _Myfirstて…
そんなのどこに書いてるんだ?まさか<vector>の中の定義に直接?
vc8には<vector>の中に_Myfirstってあるよ。 何か俺変な事書いた?
そのitatをどこに書き込んだのかを聞いてるんだけど。 内部向けのメンバなんて普通は使えない場所にあるはず。
<vector>内部のbeginとかが出てくる所に
任意の要素のイテレータって、 vector<int> v; //... vector<int>::iterator itr = v.begin() + t ; じゃだめなの?
vector いじるなよw
うは、カオスメーカw
std::advance
vector書き換えるなんて・・アホスw
vector を継承した独自の my_vector を作ればいいんじゃね?俺もそうしてる まあメンバ関数1個増やしただけだが
継承じゃなくてコンポジションだよな? vectorってデストラクタがvirtualじゃないからis-a継承すべきじゃないし。
派生クラスで必要なデストラクションが1つもなければ 一応大丈夫ではある。
>>877 いやー vector にアップキャストして delete したら未定義動作になるみたいだぜ。
5.3.5p3
"if the static type of the operand is different from its dynamic type, the
static type shall be a base class of the operand’s dynamic type and the
static type shall have a virtual destructor or the behavior is undefined."
逆に言えばアップキャストしてdeleteしなければOkとも言える。 でも元々の用件は870で事足りるがな。
まあ確かに vector を new することはないかなあ。
vector< vector<T> > という風にすることがなくはないかもしれん。
別にそれではアップキャストしてからの delete は発生しないな。 だから問題ない。
コンテナに機能追加するならわざわざ継承なりコンポジションなりしてメンバ関数追加しなくても、 コンテナかイテレータを受け取るテンプレート関数つくればいいだろ。 一部ではメンバ関数でなく外部に分離するのが推奨されてるらしいし。
>>881 それで vector が new されるとでも思ってるの?
そんなことは決まってないし、たぶんそんな実装は存在しない。
placement new も new だぜ
でも881ならどうせアップキャストされることはあるまい。
vector< vector<T> >の外側のvectorの要素へ vector派生クラスのオブジェクトを追加しようとしたら、 スライシングが起こるだろうけど、それは別問題だな。
つか未定義だったのか…知らなかった じゃあ例えばさ、windows.h の RECT 構造体を継承した CRect クラスをつくるのもNG? でも MFC ってそんなことしてなかったっけ 問題の起きうる使い方をしなければOKなのかな
継承はしていなかったような。
> じゃあ例えばさ、windows.h の RECT 構造体を継承した CRect クラスをつくるのもNG? MFCはよく知らないが、これはpublic継承ならば明らかにNG。 基本的に仮想デストラクタを持たないクラスはpublic継承してはならない。
>>893 の考えによるとMFCは基本的ではないわけか
>>891 CRect を new して RECT* で delete しなければ問題ない。
一様RECTってこんなんだぞ typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT; リソース開放なんてないから、public継承してもいいだろ
そのコンパイラで大丈夫と保証されてるならどうでもいい話だ。
899 :
983 :2007/07/08(日) 20:24:03
>>894 さっき言ったようにMFCはよく知らないが、MFCでpublic継承を使っているとしたら明らかに多態のためだろ?
それなのに仮想デストラクタにしていないはずがない。
仮にそうなっていないとしたら確かに基本的どころか糞だな。
多態のためじゃねー。 RECT は C でも使えるようにしてある構造体だから、仮想デストラクタには「できない」。 RECT を C++ で便利に使いたいがために作られたラッパクラスが CRect だ。
template <typename _T> class CRect; みたいなものないのー?
>>902 その CRect を作る人と使う人が同じなら、それでいいんだけどな
つーか、VC++ ではアップキャストして delete しても問題ないんだから どうでもいいんだろ。
905 :
983 :2007/07/08(日) 21:19:50
>>900 なるほど。
要するに単なるラッパーなんだな、public継承なんて馬鹿はやってない。
? public 継承してるぞ?
ソースきぼん
RECT の left だの top だのといったメンバ変数を CRect でも直接アクセスできるようにしてるんだな。 それでいて、RECT& を引数にとる関数に直接渡せる。 問題になる環境なんて実際存在しないっつーのに仕様に厳密にするよりは、 利便性を優先したっつーことだろう。
910 :
893 :2007/07/08(日) 21:58:04
>>909 CRect を作ったときには
>>878 のような明文化されたルールがなかった可能性も高い。
RECTおよびRECTのメンバをCRectのメンバにして、operator RECT&( )を定義すれば安全に… リソースの無駄か
MFCやATLってのはVC++で動きゃいい(それ以外の環境は保証して無い)んだから、 VC++で動けば問題ないってことだろ
CRectやCSizeなんかnewすることなんて無いし
配列でなら new することはあるけどな。 アップキャストして delete することはないが。
916 :
907 :2007/07/08(日) 22:43:34
ぉぉぅ、ソースじゃなくてドキュメントがktkr
918 :
907 :2007/07/08(日) 23:14:10
919 :
デフォルトの名無しさん :2007/07/16(月) 18:14:54
初歩的な質問ですけど、ある反復子 iter があって *iter.end() として何らかの操作を施しても合法なのかな? 番兵にしたいだけなんだけど。
>>919 だめ。end()の逆参照を行った結果は未定義。
コンテナのコンテナ?
たしかにコンテナのかわりに配列で考えたらダメなのは明白だわな。 たまたま問題ない場合も多いけど未定義は未定義だ。
&vect[vect.size()]が違法なんだよね &arr[ elementof(arr) ]はたしか合法だったけど
>>923 配列の場合添え字が一つ超えた時のアドレスを取るのは合法だが
コンテナでは未定義。あくまでもend()を使うべき。
endでも、vectorをポインタにできないじゃん。
添え字が一つ超えたイテレータはok つうかコンテナの要素をアドレスで考えちゃいかんよ どういう実装になってるのかわからないんだから
規格上は&(vec[n])はポインタとして使えるようだけど VC7ではmemcopy/memsetに渡すと落ちるなぁ
>>927 nがcapacity未満の時だけ?
それとも任意のn?
size未満が有効なのは確かだよね。そうじゃないとAPIに渡せない
>>928 std::copyとかfillで問題無しでmemset/memcpyで落ちるから不思議。
シャローコピーとディープコピーの問題じゃないかな。
そもそもコンテナの中身をmem系関数で操作するのは許されてないんじゃないか?
配置上は許されるはずだが。 コピーオンライトみたいな仕掛けがあるんだろうか。 >ベクトルの要素は隣接して格納される。 > v が<T, Allocator>でT がbool以外のの場合 、 >0 <=n<v.size() の時 &v[n] == &v[0] + n となることを意味する
VCならステップ淫してみりゃおk
もういい加減vector<bool>の特殊化は消すべきだと思う
>>927 そっから先に要素は無いんだから、当たり前じゃね?
いいかげん GetBuffer() が欲しいです &v[0] は empty チェックを外でやらないといけないのがめんどい
GetBufferならv.reserveすれば良いと思ったが違うのかな。
ごめん、resizeだった。
>>938 !!! チェックしてなかったわちょーさんくす「
>>933 vector<boost> の特殊化を消すって?
特定のクラスを引数に取ったときだけ
クラステンプレートの特殊化を禁止するなんてことできるの?
なんか俺根本的にテンプレートを理解してない?
そもそもvector<boost>の時点で
>>940 は何かがおかしい。
>そもそもvector<boost>の時点で
>>940 は何かがおかしい。
そりゃぁ、>940の頭だろ。
今更仕様から取り除くことはできないな。 利用してるプログラムが軒並みアウトになっちまう。 bool と全く同じように扱えるクラス __bool を標準で提供して、 vector<__bool> とできるようにするとかなら可能。
sstreamみたいに段階を経て亡き物とする方法も。
名前が変わったんだっけ?
vector<bool> の代わりとなるクラスを作って、 今まで vector<bool> としてあったところをそれで置換してもらう、 っつー形に強引にすることはできんのかね。
list と vector を 使って sort 以外同じ書き方でできるの内容のプログラムなので 切り替えて使っているのですが、sort を使いたくて困りました。 sort も使いたいのでコンパパイル時に切り替えたいのですが; 自前の #define を使ってではなく、その変数が、list か vector かによって 条件コンパイルする方法はないでしょうか? 実行時では、sort 部分がコンパイルエラーになるので間に合いません。
なんだかよく分からんがオーバーロードを駆使して解決できそう
イテレータのトレイトに対してオーバーロードされたテンプレート関数を作る。 std::advance関数の実装が参考になるよ。
コンテナのイテレータがランダムアクセスイテレータならstd::sortが使えて、 両進イテレータならメンバ関数のsortが用意されていることを期待するわけだ。 C++はこういう見えにくいインターフェースを多用するから困る。
そのためにコンテナのイテレータのタイプに合わせて コンパイル時にどちらを使うか決定してくれる奴があったと思うけど・・・
そんな便利な記法STLにあったっけ がりがりオーバーロード書いてたよ。 今からリファレンス読み返してくるorz
boost::sortはenable_ifを使って 渡されたコンテナにメンバとしてsort()が定義されている場合はそれを使い 定義されていない場合はsortアルゴリズムを使うように定義されてるみたい というわけでこれを使うのが楽っぽい?
>>951 そこでコンセプトですよ。
今までただの文書にするしかなかったけど、
今度、言語仕様に組み込まれそうだし。
traitとconceptの違いが分からない modern C++ design読めってことですかそうですか
イテレータは、ポインタまたは、 std::iterator を継承していることが必須条件 だから、どちらの場合でも、iterator_category でイテレータの特性を知ることが出来るよ。
>>956 trait は型について問い合わせるために使える個々の情報。
concept は型が満たすべき条件と意味づけをひとまとめにしたもの。
>>957 イテレータは別にstd::iteratorを継承する必要はなく、十分条件に過ぎない。
それを継承すれば、その型に対して簡単にiterator_traitsが使用可能になるというだけ。
でも、iterator_traits が使えないと、advance と distance を個別に実装しないと動かない罠
std::iteratorを継承せずとも、自分でイテレータのクラスに value_typeやiterator_categoryなどを定義すれば、 iterator_traitsは使える。 iterator_traitsを特殊化するというもっと荒業めいた方法もある。
テンプレート特殊化って 既存のクラスに後からトレイトやらコンセプトやら 情報を書けるから便利だよな。 これぞ再利用。
strsteamの間違いだろ。
ボケなのか素なのか分からないよ
VC8のiostreamなんですけどね 読み書きするたびにmutex確保するんですよ 無駄なんですよ なんとかなりませんかね
ならん。 もうシングルスレッドの時代は終わった。
直接いじくるんならstdを使う価値があまりなかったり・・・ できればpolicyやらで制御できてほしかったンですけどネ・・・
STLport(5.1.1)の設定システムがよくわからないんだけど、 host.hがSTLのビルド時に使う途中変更不可の設定で、 user_config.hがSTLを使うプロジェクトによって変更してもいい設定、 という理解で良い?
>>970 レスありがとうございます。
チェックいたしましたが、iostreamでは参照されていないようです・・・
STLPortはシングルスレッド版のiostream用意してなかったっけ 最近のバージョンはそのあたりのビルドがめんどくさくなったが
974 :
デフォルトの名無しさん :2007/07/23(月) 20:29:06
C++でデータマネジメント用のライブラリなんてありますか? マージしたりマージしたり・・・・
何をどうマージするの?
976 :
デフォルトの名無しさん :2007/07/23(月) 21:13:30
C++でETLはありだな。
もうミンナについて行けない。 もだんなんとかって本読むよ
もだんなんとかは勉強になるけどちょっとふるいな
>>978 theoretically interesting for some people, but practically useless!
boost::mpl本の和訳ってまだ出てないんだよなぁ…
981 :
名無しさん@そうだ選挙に行こう :2007/07/29(日) 12:14:04
class CTest{ public: int nNo; //学籍番号 char szName[20]; //生徒名 int nTensu; //テスト点数 } 上記のようなクラスのインスタンスをvectorに格納しておいて 場合によって、ソート条件を変更したいのですが、どのように すればいいでしょうか? 学籍番号ソート、生徒名ソート、点数ソートなどしたいのですが。 ソートの為の比較演算子だと1パターンしかソート条件を定義できないような 気がして・・。 operator<(const CTest &a)const{ return nTensu < a.nTensu; } どなたかご教示の程、お願いしますm(__)m。
>>981 std::sortに好きな比較関数オブジェクト作って渡せば?
>>981 素直にやるなら
>>982 邪道な方法としてはメンバ変数にソート用のフラグを用意して、
それをもとにoperator<() の中で分岐
フラグはソート前にセットする。
というか典型的な関数オブジェクトを活用するパターンだよな
986 :
名無しさん@そうだ選挙に行こう :
2007/07/29(日) 13:29:29 関数オブジェクトをキーワードにサンプルを探せました。 どうもありがとうございましたm(__)m