【C++】template 統合スレ -- Part2
otu
オモシロイリンクダナ
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>10
意地でもマ板にリンクしたい奴の数→(1)
意地でもマ板にリンクしたい奴の数→(65536)
14 :
デフォルトの名無しさん:03/03/20 20:10
shared_ptrから生ポインタを取り出す方法を教えてください。
というか、shared_ptrから別の型のポインタにキャストする方法を
教えてください。
(Any *)&*sp;
>>14 他にもこんなのがある。
template<typename T, typename U>
shared_ptr<T> shared_static_cast(shared_ptr<U> const & r); // never throws
template<typename T, typename U>
shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r);
template<typename T, typename U>
shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r);
template<typename T, typename U>
shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r); // never throws
18 :
デフォルトの名無しさん:03/03/20 20:25
どうもありがとう。用意されているならそれを使ってみます。
ところでなんで
>>16のやつって間に&が必要なんですか?
(Any &)*sp;
20 :
デフォルトの名無しさん:03/03/20 21:11
VC6でSTLPort使てた時Debugでビルドした時
void Foo(const std::vector<std::string>& v)
{
std::vector<std::string>::iterator it;
for(it = const_cast<std::vector<std::string>::iterator>(v.begin()); it != v.end(); ++it){
...
}
}
で、
error C2440: 'const_cast' :
ってでます。
VC6付属のSTLではリリースビルド、デバッグビルドともにエラーは出ません。
STLPortを使った時もリリースビルドならエラーは出ません。
今はifdefでSTLPort使てた時Debugビルドの時だけ
void Foo(std::vector<std::string>& v)
{
std::vector<std::string>::iterator it;
for(it = v.begin(); it != v.end(); ++it){
...
}
}
とconstを外したものを使うようにしていますが
ソースが見にくくてしょうがないです。
何か良い方法はありませんか?
void Foo(const std::vector<std::string>& v)
{
std::vector<std::string>::const_iterator it,last;
for(it = v.begin(); it != last; ++it){
...
}
}
つーかSTLをもっとちゃんと勉強しましょう
Effective STLとかね
あ、
last=v.end()
を追加してくれーーーーーー
23 :
デフォルトの名無しさん:03/03/20 22:11
>>21 ありがとうございます。
>>つーかSTLをもっとちゃんと勉強しましょう
つくづく実感しました。
gcc 3.2.2 で boost::lambda が使えない?
#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <boost/lambda/lambda.hpp>
int main(int argc, char** argv) {
std::vector<char*> v;
std::for_each(argv, argv + argc, boost::bind(boost::mem_fn(&std::vector<char*>::push_back), &v, _1));
std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << std::endl);
return 0;
}
>>24 std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << '\n');
で我慢しとけ。
std::endl は認識できない。
for(it = c.begin(); it != c.last;() ++it) のかわりに for_each を使ったほうがいい局面って
少ないような気がする。
28 :
デフォルトの名無しさん:03/03/21 11:50
list < shared_ptr<MyClass> > ls;
というリストから、ls.erase(iter)などで要素を削除するときに、
リストから削除されるのは、基本的にポインタだけなのですよね。
このようなスマートポインタの場合、ちゃんとポインタが指すオブジェクトも
解放されるのですか?
また、普通のポインタの場合は、ちゃんと自分でdeleteもしないといけないのですか?
>>28 スマートポインタの場合、ちゃんとポインタが指すオブジェクトも解放されるのです。
普通のポインタの場合は、ちゃんと自分でdeleteもしないといけないのです。
>>25 サンクス。でも何だか悔しい…(´・ω・`)ショボーン
>>26 そうかなぁ、俺は逆に for 使って書く方が少ないかも。
int hoge[] = {0, 1, 2, 3, 4};
for (i = hoge.begin() ; i != hoge.end() ; ++i) {
....
}
って書けんだろ?やってる事が同じなのに、コンテナに入ってるか
配列に入ってるかの違いだけで、アクセスする方法も変わるのは、
なんだか美しくない気がする(なんじゃそりゃ)。
>>30 lambdaに << std::endl; が通らないのは、よくわからんが
endlのテンプレート・パラメータがうまく解決できてないからのような
気がする。boost::lambdaが改良されればこのコードも通ると思う。
>>30 boost::arrayを使えばいいやん
34 :
デフォルトの名無しさん:03/03/21 19:14
shared_ptrを明示的に解放するにはどうしたらいいんですか?
まさかNULLとか関係ないポインタを代入させて(参照を0にすることで)
解放するわけじゃあないですよね。
>>34 Q.Why doesn't shared_ptr provide a release() function?
A.shared_ptr cannot give away ownership unless it's unique()
because the other copy will still destroy the object.
とDOC中にありますので、明示的な解放はヤバイという事です。
む。じゃあNULLを指せばいいのかな(笑
>>36 それも危なげ。
class A {
public:
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
int main()
{
boost::shared_ptr<A> a(new A);
boost::shared_ptr<A> b(a);
std::cout << a.use_count() << std::endl;
a.reset((A*)0);
std::cout << b.use_count() << std::endl;
}
というか、なんで明示的な解放が必要なのか?
int main()
{
boost::shared_ptr<A> a(new A);
boost::shared_ptr<A> b(a);
std::cout << a.use_count() << std::endl;
std::cout << *b->p << std::endl;
a.reset((A*)0);
std::cout << b.use_count() << std::endl;
std::cout << *b->p << std::endl; // あぼ~ん!!
}
じどうてきにかいほうしてくれないから
スマソあぼ~んはしないわ。
だったらなまぽにしなされ
>>40 だったらスマートポインタなんて使うなYO!
だったらぬるぽいんたを使いなされ。
え、みんなスマートポインタを使うときは解放しないの?
しませんガッ何か?
え、みんなガーベッジコレクション使う時は解放しないの?
ガベコレの場合は手動で開放する場合もあると思うんだが…。
デカいデータを扱った時とか。100% 開放してくれるわけじゃないし。
手動で開放?
あるオブジェクトを指定して解放というのは一般的な言語でできるの?
shared_ptr の話だろ?
> デカいデータを扱った時とか。100% 開放してくれるわけじゃないし。
って何だ?相互参照しまくりって事か?
>>49 Boehm GC。ていうか C++ スレだし。
>>50 参照されてないからって100%開放されるわけじゃないよ。
shared_ptrって参照カウンタらしいから
参照が0になれば開放されるのかと思っていた
>>52 いや、開放されないのは GC だって…文脈読んでくれよ…。
shared_ptr はメモリリークしない??
話が見えないんだが、今 shared_ptr とガベコレとの全く違う話が
並行してるのか?
>>51 どーゆー時に開放されないのか教えてたもれ。
ソース追った感じだとリファレンスカウントゼロになった時点で
checked_delete(ptr)、すなわち delete p が呼ばれてるようだが・・・
>>54 その通りだよ。下のプログラムではaもbも0にリセットした途端に
Aのデストラクタが呼ばれる。
int main()
{
boost::shared_ptr<A> a(new A);
boost::shared_ptr<A> b(a);
std::cout << a.use_count() << std::endl;
std::cout << *b->p << std::endl;
a.reset((A*)0);
std::cout << *b->p << std::endl;
std::cout << b.use_count() << std::endl;
b.reset((A*)0);
std::cout << "still running." << std::endl;
}
>>55≠51なんだよな?
じゃないと全然
> 参照されてないからって100%開放されるわけじゃないよ。
の説明になっていないように見えるんだが…。
>>56 boost::shared_ptrのDOCを隅から隅まで読んでみたが、確かに
「参照している数が0になった途端にデストラクタが呼ばれる」とは
どこにも書いてないね。
メモリリークを起こさず、CopyConstructible and Assignable なので
標準コンテナに入れられるような事しか書いてない。
>56
>参照されてないからって100%開放されるわけじゃないよ
これはおそらくBoehm GCが保守的なGCを行っているので(他のゴミ値がオブジェクトへのポインタの可能性があるので)
そういったのだと思う
ちょっと待てぇ~。大混乱中。俺は>50で
> shared_ptr の話だろ?
と書いたら>51で
>
>>50 > 参照されてないからって100%開放されるわけじゃないよ。
と書かれたんだから、
「shared_ptr でも参照されてない時でも開放されない場合がある」
って>51は言ってるんだよな?ここで
「『ガベコレの場合は』参照されていない時でも(まだ)開放されない場合がある」
とか言ってるわけじゃないんだろ?とりあえず>51降臨してくれ。
気になって夜も眠れ・・・たけどさ(w
# もし>53=>51なら文脈読めてないのは>53の方なわけだが…
なんかアラシみたいになってスマソ
すまんが>51降臨期待ageさせて頂きまふ。
あぁ、なんか分かったぞ。とりあえず
>>48は
>>47のネタレスへのレスなんだな。
だから本来は放置していいはずなんだな。なんだ、それだけか。
お騒がせスマソ。
62 :
デフォルトの名無しさん:03/03/22 13:28
つまり、shared_ptrが指すオブジェクトを今すぐ解放したい場合は、
どうすればいいのだ?
delete p.get();
shared_ptr<foo> *p = new shared_ptr<new foo>;
// ima sugu
delete p;
C++使いは手当たり次第に外部ライブラリ試している暇があったら
一度は費用対効果というものを真剣に考えてみる必要がある。
習得コストや可読性を考えるとほとんどの開発者が
コストを回収しきれていないのが現実。
そのコストを貴重な休日で穴埋めしたいならそれでもいいけどさ。
66 :
デフォルトの名無しさん:03/03/22 13:38
はなしに関連性がないけど
vc7ってtemplateの部分特殊化みとめてないんですね。
>>65 マジレスすると標準ライブラリだけでゴリゴリ書いてるコードの方が
汚なくて読めないし、生産効率も悪い。
ほとんど同じコードをダラダラ書いてるのが綺麗だとでも思ってんの?
セオリックをまとめた外部ライブラリは習得しても無駄じゃない。
// いや、メタプログラミングとかはアレだけさ
>>62 そのshared_ptrが指すオブジェクトがあって
そのオブジェクトを指す、すべてのshared_ptrを今すぐ廃棄する
>>68 非標準ライブラリってそう簡単に導入できるものじゃないと思うけど。
実際に導入したプロジェクトの規模・人数・ライブラリの種類ってどんなもんなの?
うちの会社は標準ライブラリのSTLですら使用禁止ですが、何か?
72 :
デフォルトの名無しさん:03/03/22 15:29
>>71 ごちそうを目の前にして食べられずにいるような心理状態か。
まあマ板向けの話題だな。
>>71 API直書きですか?
それでMFCとか使ってたら笑えるけどな
まあ、ライセンスの関係もあるから仕事で使うときは注意がいるわな。
いや、周りがCしか使えない人ばかりで
その人たちが言うにはSTLなんて信用できないそうだ
お前たちの書くコードよりも遥かに信用できるワイ!ってあの人が言ってました
STLのコードの方が信頼できるけど
厨がSTLを使って書いたコードは信頼出来ない
STLは両刃の剣age
T* の引数をとって、そこに値を格納するようなAPI に対してboost::shared_ptr<T>を
使うにはどうしたらよいのでしょうか?
一時変数を使うしかないですか?
boost::shared_ptr<T>::get
>>82 渡されたAPIがshared_ptrのカウンタに干渉する可能性は無いわけだが。
>>80 shared_ptr<T> p( new T());
f(p.get());
>80ですが、T**の引数の間違いでした。すいません。
shared_ptr<T> sp;
T *p;
func(&p);
sp.reset(p);
>>80 そのAPIから返されたポインタをdeleteで削除することにしていいのか?
そういう引数を使って返すということは、freeか専用の解放APIとかじゃないか?
>>85 ひょっとしてDirectXとかのCOMのAPIじゃないの?
だとしたらCComPtrがいい。COMに適したスマートポインタ
違っていたらまことにあいすまん
89 :
デフォルトの名無しさん:03/03/23 11:51
すまんで許されるのかね?
跪け!命乞いをしろ!
バルス!?
めがぁぁ、めがぁぁ(#ノωノ)
天プレートの城ラピュタ
アニオタうざい。他んとこでやれよ。
96 :
デフォルトの名無しさん:03/03/23 20:14
boost::spiritに俺様の指向性アンテナがビンビンなんだが
業務で使うのがVC6/7なんで試そうかどうか悩み中。
誰か試してないか?
>>97 boost::spiritは1.30から加わったパーサもどきらしいですね。
今Boost-jpで日本語訳をするかどうか検討中。
#それよりも1.29の訳を早く終わらせねば。
enumに浮動小数使えるコンパイラ無いの?
>>101 俺もよくわからん。cppllでパーサとして使えるというのが流れて
いたから。もどきではなくてもしかして本物か?
そうするとC++でPHPなんか書けてしまうとか?
>>103 Boost1.30出てるから、落として解凍した方がいいよ。
イカレてるな
106 :
デフォルトの名無しさん:03/03/24 21:40
STLには多倍長の計算ができないですよね。
みなさんは必要なときどうやっていますか?
足し算引き算くらいだったら自分で作れるけど、
巨大な数と巨大な数の割り算とか実装するのは大変なので。
多倍長整数のクラスをどっかから拾ってきてコンテナに放り込めばいいだけでは?
どっかから?
おれたちのせかいから!
>>104 ありがとう、落としてみたよ。19日に 1.30 出てたんだね。
新しく増えてるモノで遊んでます。
>>106 boost::rational のドキュメントに、
> Note: Should the boost library support an unlimited-precision integer
> type in the future
とあるので、将来的には boost::integer なんてできるかも、できないかも。
どっか=イラクの大統領宮殿
>>106 GMPでもMintでも好きなのを使えばよい。
115 :
デフォルトの名無しさん:03/03/25 16:01
教えてください
標準C++ライブラリで、うまいことワイド文字(列)をマルチバイト文字(列)に
変換したり、その逆の処理をするクラスないし関数ありませんか?
>>115 微妙にスレ違いだが、テンプレートを利用するなら、std::ctype を使えばいいかも。
std::wstring source = L"(・∀・)";
std::string result( source.size(), char() );
const std::ctype< wchar_t >& ct = use_facet<std::ctype<char> >( std::locale() );
ct.narrow(source.data(),source.data()+source.size(),' ',&result[0]);
assert( result == "(・∀・)" );
うまく良くかは知らん。
なんかいろいろ間違えてたっぽい。
いろいろ手直しして、VC++.NET で動作確認。
std::localeloc( "japanese" );
std::locale::global( loc );
std::wstring source( L"(・∀・)" );
std::string result( source.size()*2, char() );
const std::ctype< wchar_t >& ct = std::use_facet< std::ctype<wchar_t> >( loc );
ct.narrow( &*source.begin(),&*source.end(),'?',&result[0]);
std::wcout << L"wide : " << source << std::endl;
std::cout << "narrow : " << result << std::endl;
結果
wide : (・∀・)
narrow : (・∀・)
マルチバイト文字列からワイド文字列へは、
std::string source( "(・∀・)" );
std::wstring result( source.size(), wchar_t() );
const std::ctype< wchar_t >& ct = std::use_facet< std::ctype<wchar_t> >( loc );
ct.widen( &*source.begin(),&*source.end(),&result[0]);
とすればいい。
おしまい。
>>117 ありがとうございます。参考になりました。
でも、
>>119 をみると、どこでもつかえるわけではないようですね。
うーむ。2バイト文字ってまだイマイチなんですね…
122 :
デフォルトの名無しさん:03/03/26 17:15
【質問】
下記のTYPENAMEにはクラスDDDDを継承した物が入らなければならない、
という事を実装する方法はありますか?
もし、ありましたらそれを教えてください。
template < typename TYPENAME > class AAAA {};
class BBBB : public DDDD {};
class CCCC {};
class DDDD {};
AAAA<BBBB> aaaa_bbbb; // ok
AAAA<CCCC> aaaa_cccc;// ng
AAAA<DDDD> aaaa_dddd; // ok
無い
>>122 LokiでSUPERSUBCLASSとSelectorを組み合わせて・・とか
Lokiで
STATIC_CHECK(SUPERSUBCLASS(DDDD, TYPENAME), TYPENAME_must_be_a_subclass_of_DDDD);
Loki ですか。見てみます。
どうもありがとう。
Lokiの SUPERSUBCLASS(B, D)ってBがDのあいまいなベースクラス
のときはコンパイルエラーになるんだね。
class Base{ };
class Derived1 : public Base { };
class Derived2 : public Base { };
class DerivedD : public Derived1, public Derived2 { };
SUPERSUBCLASS(Base, DerivedD);
↑
これダメ
class Derived1 : virtual public Base { };
class Derived2 : virtual public Base { };
じゃねーのか?
AAAAの実装のどっかにTYPENAME型をDDDD型の参照で受けるコード混ぜとけ。
>>128 もちろんそれならOK
>>129 わざわざLokiを持ち出す必要がないときは
それがお手軽でいいね。
131 :
デフォルトの名無しさん:03/03/27 15:47
今boost::shared_ptrを初めて使い、
言語が変わったと思うくらい感動してるのですが…。
VC6のメンバ自動表示が効かなくなるのは
やはりどうしようもないのでしょうか?
boost::shared_ptr<MyClass> mc( new MyClass() );
mc->
↑ここでいつも出るやつです。
どうしようもないれす
やはりそうですか…レスありがとうございました
ガックリ_| ̄|~~○ヌルポー
というか、原理的に不可能だと思うのよ。それは流石に。
「原理的に」だとコンパイルも出来ないですが
boost::shared_ptr<MyClass> mc( new MyClass() );
mc.operator->()->
とかってすれ。で、メンバを選択後、".operator->()" を削除すると。・・・うざー。
ひょっとしてshared_ptr系のメンバ表示させようしたら、参照カウンタがインクリメントされたりとかしない?
あと、shared_ptr系のポインタ欲しい場合
HOGE* func(){
shared_ptr<HOGE > hoge_sp(new HOGE );
return hoge_sp.get();
}
//HOGE*が デリートされたらマズー?
shared_ptr<HOGE > func(){
shared_ptr<HOGE > hoge_sp(new HOGE );
return hoge_sp;
}
//なんかカウンタがあやしいことになtってそー
//返り値でエラーのチェックもできなそー
void func( shared_ptr<HOGE >& hoge_sp ){
hoge_sp =shared_ptr<HOGE >( new HOGE );
}
//引数とるのめんどくさーーー。
の、どれが適当でつか?ていうか、みなさんどういう風にしてます?
shared_ptr<HOGE > func(){
return shared_ptr<HOGE >(new HOGE );
}
>>138 > shared_ptr<HOGE > func(){
> shared_ptr<HOGE > hoge_sp(new HOGE );
>
> return hoge_sp;
> }
に何の問題があるのかさっぱりわからんのだが?
shared_ptrの正しい使い方がよくわからんので、すんまそん。
えーと、 func の中でfucn2を実行して,func2がうまくいった場合のみポインタかえしたんだけど、
失敗したら、shared_ptrにNULLポインタ代入できないからどうしましょうと、、、、
shared_ptr<HOGE > func(){
if( ! func2 ){
shared_ptr<HOGE > hoge_sp(new HOGE );
hoge_sp.get().m_is_func2 = true
hoge_sp.get()->Init();//func2がうまくいったのでhoge_spの処理などしてみる
return hoge_sp;
}
else{
//func2 が失敗したから なんか失敗したことを返したいのだが。。。
//thorwはなしの方向で・・・・。
shared_ptr<HOGE > hoge_sp(new HOGE ); //とりあえず new?
hoge_sp.get().m_is_func2 = false;
return hoge_sp;
}
}
なんか激しく違う感じが。。。
普通はnewしたあとに何らかの処理をしないで、すぐreturn するもん?
boost::optionalじゃね?
>>141 よくわからんが、お前が書いた文章を最大限に汲み取って考えると、こうか?
shared_ptr<HOGE > func(){
shared_ptr<HOGE > hoge_sp;
if( ! func2() ){
hoge_sp.reset(new HOGE );
hoge_sp->Init();
}
return hoge_sp;
}
>>145 そんな感じ。
int test()
{
shared_ptr<HOGE > ret = func();
if(hoge.get()== NULL) return "アボーン";
}
でいいのか・・・。
みなさん、ども、ありがとうございますた。
ていうか、実はC言語でも使えるように _std_callとかつかってshered_ptrが握ってる
ポインタ返す場合どうしたらよろしいのかと、思ったわけでして、
shared_ptr<HOGE > func();
以外の方法ないのかなーと、聞こうとして、ぜんぜん別な こと聞いてマスタ。
>>142 今、boost::optional みてみた。
いいすね、これ。
>>146 そのコードもはてしなく意味不明だがともかく、
hoge = shared_ptr<HOGE>(); // 何もポインタを突っ込んでないshared_ptrはNULL扱いになる
if( !hoge ) return "アボーン"; // get() しないでも ! でnullチェックできる
くらいは覚えといた方がいいぞ。
> ていうか、実はC言語でも使えるように _std_callとかつかってshered_ptrが握ってる
> ポインタ返す場合どうしたらよろしいのかと、思ったわけでして、
自分のコードじゃない外部の関数に渡すその瞬間で、
shared_ptr<>のget()を使って生ポインタに戻すので大抵は十分だと思われ。
shared_ptr<HOGE > hoge_sp(new HOGE );
↑こんなん書いといて、「thorwはなしの方向」って、そりゃムリだ。
みなさま、どうもありがとうございました。
ドキュメントとソースきちんと除いてから、でなおしてきます。
151 :
デフォルトの名無しさん:03/03/31 14:17
Modern C++ Design と Generic programming―STLによる汎用プログラミング
どっち買った方がいいかなぁ。資金的に両方は無理なのよ。
>>151 前者はLokiのデザインパターンを中心に書かれている。初心者には無理。
後者はSTLの本当に基本的な部分が詳細に書かれている。初心者向き。
本当は両方欲しいんだけどね・・・・全然傾向が違う本だから。
>>152 thx. じゃ、Genericの方にしとこうっと・・・
ま、今日株が下がらなければ両方20冊ずつぐらい買えたのだが・゜・(ノД`)・゜・。
小泉とブッシュは早く氏ね
154 :
名無しさん@XEmacs:03/04/01 18:31
155 :
デフォルトの名無しさん:03/04/02 16:37
どうにも弱ってます。質問お願いしたいのですが、
vectorのreserve等で確保した領域を、
明示的に解放する方法というのは無いのでしょうか?
>>155 こうやると大抵縮んでくれるよ。処理系によってはこれでも駄目な場合が
あるから一応確認してね。
int main()
{
std::vector<int> v;
v.reserve(1000);
std::cout << "capacity = " << v.capacity() << std::endl;
std::vector<int>(v.begin(), v.end()).swap(v);
std::cout << "capacity = " << v.capacity() << std::endl;
}
std::vector<int>(v).swap(v);
こう書いた方が簡単だね。
>>156-157 すいません、理解するのに時間がかかりそうなので、
先にお礼をさせてください。レスありがとうございました。
しかし、これはすごい・・・・荒技ですね。
ちょっと恐かったりも(笑
159 :
デフォルトの名無しさん:03/04/02 17:00
mapってイテレータで順次アクセスできるけど
内部的にはリストか何か保持してるの?
>>158 Effective STLの17項「swap技法」というのを読んでご覧。
>>159 赤黒木で深さ優先探索というのをやっている物が多いそうだ。
>>160 さすが凄いことしてるな。ちょっと勉強してみるか。がりがと。
>>160 参考資料の紹介ありがとうございます。
早速図書館で調べてきます。
>>156 なんでこれで縮むんだろうか?
わからん・・・
>>163 確か、allocator_typeが同じであれば
単に内部配列のポインターを入れ替えてる
だけだったハズ。処理系にもよるけど。
>std::vector<int>(v).swap(v);
コンストラクタでいきなりメンバー呼び出してもOKなの?
…しらんかった…。
>>164 コンストラクタで呼び出しているのではなく、
キャストによってできあがった一時オブジェクトに対してメンバーを呼び出しているんです。
>>165 >キャスト
ああぁ…そういうことか。
すばらスィ勘違い。
つっこみTHX
漏れはこっちのほうが分かりやすくて好きだ。
v.swap(vector<int>(v));
>>164 std::stringとかでよく、s1 + s2 + s3;などと書くのと一緒。
これは結局、std::string(s1 + s2).operator+(s3);
しまった!v.swap(vector<int>(v));はうそ。
一時オブジェクトは非const参照で渡せなかった・・・
どうも納得いかなくて試してみたら、
ヤパーリコンストラクタだった…。
#include <iostream>
using namespace std;
struct clsA{
clsA(){cout<<"clsA::clsA()"<<endl;}
clsA(const clsA& a){cout<<"clsA::clsA(const clsA&)"<<endl;}
void swap(clsA& a){cout<<"clsA::swap(clsA&)"<<endl;}
operator clsA(){cout<<"clsA::operator clsA() const"<<endl;return *this;}
operator clsA&(){cout<<"clsA::operator clsA&() const"<<endl;return *this;}
};
void main(void)
{
clsA a;
clsA(a).swap(a);
}
----
clsA::clsA()
clsA::clsA(const clsA&)
clsA::swap(clsA&)
(コンパイラ:VC5)
でもそうなるとなぜclsA a.swap(a);がダメなのかよくわからん…。
ってか、スレ違いでスマソ。
×:でもそうなるとなぜclsA a.swap(a);がダメ
○:でもそうなるとなぜclsA a().swap(a);がダメ
>>170 それやると a が空っぽになっちゃうだろ。
>>171 あ、clsAはあくまでもテスト用のクラスなので、
記述も例えで書いてあります。
ちなみにswap(clsA&)は表示以外なにもしない。
SampleMFC error LNK2005:
"public: __thiscall _STL::basic_string<char,class _STL::char_traits<char>,
class _STL::allocator<char> >::~basic_string<char,class _STL::char_traits<char>,
class _STL::allocator<char> >(void)"
(??1?$basic_string@DV?$char_traits@D@_STL@@V?$allocator@D@2@@_STL@@QAE@XZ)
は既に定義されています。
意味がわからない
_
>>169 コンストラクタだった、ではない。
キャストのときには一時オブジェクト作成のためにコンストラクタが呼ばれるってだけ。
>>176 clsA(a)がキャスト?
clsA(a)は、"Explicit type conversion (functional notation)"
(clsA)aは、"Explicit type conversion (cast notation)"
なんだが、前者をキャストと呼ぶのか?
呼ぶという事にしてあげといて下さい
キャストとコンストラクタなんてやってることは同じなんじゃ…
static_cast<int>(0) // キャスト
static_cast<std::string>("foo")// キャストだが呼ばれるのはコンストラクタ
int(0)//関数スタイルのキャスト
clsA(a)(aはclsAのインスタンス)をキャストと呼ぶのは違和感あるけどね。
>>177 その両者を総称してキャストと呼んじゃってたよ。
適切な語は何? 明示的型変換かな?
「キャスト」は式。
「明示的型変換」も式。
「型変換」は動作。
「コンストラクタ」は関数。
キャストまたは明示的型変換で型変換が行われる。
型変換にはコンストラクタが使われる。
・・・ということでよろしいか?
>>179 ホントだ。
なんかキャストとコンストラクタ
の境界があいまいになってきた(w
>>165 >コンストラクタで呼び出しているのではなく、
粘着だけど、ヤパーリコンストラクタ。
ちなみにこれ↓でもOK。
clsA().swap(a); //デフォルトコンストラクタ+メンバ呼び出し
clsA(val1, val2).swap(a); //2引数以上のコンストラクタ+メンバ呼び出し
(VC5)
>>183 >clsA().swap(a);
型変換ではないだろ
関数テンプレートでTを推測するのは
便利でありがたいのだが…
引数でしか推測しないのかな?
戻り値ではだめっぽいのだが
template<typename T>
inline T
f(const char *s)
{
return reinterpret_cast<T>(g(s));
}
>>186 どういうこと?
推測ができないこともないのは
コンパイラベンダの努力しだい?
それともプログラマの努力しだい?
template<typename T>
inline void
f(T &t, const char *s)
{
t = g(s);
}
というのも考えたが、これだと
X x;
f(x, s);
となってしまい
const X x = f(s);
のようにconstを使えないのでいやーんと
挫折したのよ…
>>187 すまん、↑のは
const X x = f<X>(s);
のような気がする
template<class T> inline void f(char *s)
{...}
const X x=f<X>(s);
うそ。
s/inline/T/
>>187 プログラマの努力しだい。 発想を変えて考えてみよう。
>>191 なに!?ということは方法があるのだな…
つまり最終的には
const X x = f(s);
と書けるのか?
型引数を指定する<>を書かずに
ままま、まさかー!
もしや
template<typename T>
inline T
f(const char *s, const T &dummy)
{
return reinterpret_cast<T>(g(s));
}
const X x = f(s, x);
とかするのか?
ただVC7ではどうも理想どうり逝きません。
gccでは無事動きました。 VC6・・・は多分動いたと思います。
>>195 違います。
186さん、少し考える時間をもらってもいいですか?
10分ほど。
日付が変わったらもう一度かきこむよ。
わかったか、わからなかったか。
その時の返事に答えをきぼんぬ。
すまん、186さん、ヒントください。
関数オブジェクト
T operator()(const char *s) const;
みたいなのをつかいますか?つかわないですか?
関数オブジェクト・・・か、うーんおしいような気がする
>>199 だめだ、わかんないよ…
わかんないので質問したんだけど
正解をお願いします
struct f{ f(const char* s); template<typename T> operator T() cosnt; };
class Foo
{
const char *p_;
public:
Foo(const char *p):p_(p){}
template <class T>
operator T() const
{ return *(T *)(p_); }
};
Foo foo(const char *p)
{ return Foo(p); }
const int i=foo(p);
const float f=foo(p);
と出来ます。
って先に>201にかかれてますか?
なんだよー、ががーり
あ~
頭をガツンとやられた感じだ
つまりは暗黙の型変換
(の際に仕掛けを発動させる)
をするということですか?
ちなみに、これって、戻り値最適化とかが
うまく働きますか?
>>205 そう、その変換が起きるまで処理を遅延させる
>>206 それはコンパイラによるけど
template <class T>
operator &T() const;
処理内容によってはこのように参照を返すとか。
あまり複雑にやり過ぎると最適化かかりにくくなることはあるから、あまり使わないほうがいいのかもね
>>208 >あまり複雑にやり過ぎると最適化かかりにくくなることはあるから、あまり使わないほうがいいのかもね
素直に最初のままにつかっておくことにするよ
ところで、そもそもの質問で、
「関数テンプレートは戻り値をTを推測するための材料に使わない」
ということは、そうなのでしょうか?
最適化の都合ではなくて、構文解析のしくみ上の問題だった気がする。
だれかフォローしてくれ
>>209 C++は戻り値を
int func() { ... };
// int n = func();
func();
捨てて文にすることもできる言語なので、戻り値の型は推測には使えない。
戻り値を受け取っている式の時だけ推論して、そうでない使い方の時はエラー、
という仕様も考えられなくはないが、
>>210氏の書いてるように
構文上の自分の「子」以外の属性を使う…というのは言語定義が
かなり複雑になるので避けたのだろう。
class A;
class B;
void f(A);
void f(B);
A g();
B g();
f(g());
class A {};
class B : public A {};
class C : public A {};
void f(A);
void f(B);
void f(C);
A g();
B g();
C g();
f(g());
どれだゴルぁ
何がいい対価サパーリわからんが、ここは template すれだ。すれ違い。
C++ では引数が同じで戻り値だけ異なる関数は多重定義できん。
どれだ以前にコンパイルエラーだ、ヴぉけ。
> A g();
> B g();
> C g();
これが通るコンパイラがあるのかどうか知らないが・・・。
言いたいことはなんとなくわかった。
>>201のfを
void func(A);
void func(B);
の関数に突っ込んだら
func(f(s));
「どれだゴルぁ」ってことでないかい?
多分「あいまいだゴルァ!」いわれるのでは
次のようなコードがVCではコンパイルできて
gccではコンパイルできないのですが、
このコードは仕様上、認められているのでしょうか?
struct A
{
template<class T>
void Func(){}
};
template<class T>
void FuncA()
{
A a;
a.Func<T>();
}
>>217 template<typename T>
struct A
{
void Func() { std::cout << typeid(T).name() << std::endl; }
};
template<typename T>
void FuncA()
{
A<T> a;
a.Func();
}
int main()
{
FuncA<int>();
}
>gccではコンパイルできないのですが
情報なさすぎ
>>219 すいません。
mingw(gcc-3.2.1)では
void FuncA()
{
A a;
a.Func<int>();
}
のように普通の関数の中で 明示的にテンプレート引数を指定して
メンバ関数テンプレートを呼び出すことはできたのですが、
>>217のソースのようにテンプレート関数の中で呼び出すと
FuncAを実体化させない場合でも
a.Func<T>(); の部分で
parse error before `>' token
とエラーが出て、コンパイルできなかったんです。
ただ、VC.NETではFuncAを実体化させた場合でも
させない場合でも、コンパイルできたので、
ソースが間違っているのか、gccがその構文に対応していないのか
どちらなのかが知りたくて質問しました。
>>218 えっと....これはどう解釈したら?
VCでの出力は int
mingwでの出力は何故か i
になったのですが...。
>>220 i は int の i です。doubleは多分 d になると思います。
>>220 a.template Func<T>();
でどうよ?(自信無し)
>>222 おおっ、コンパイルできるようになりました。
ありがとうございます。
型名の前に付けるtypenameみたいな物が必要なんですね。
>>222 第3版のC.13.6「限定子としてのtemplate」だね。
a.Func<T>(); とした時点でコンパイラにはFunc()がメンバテンプレートで
あることが分かっていないので、'<'が比較演算子だと見なされてエラー
になる。
待て。
>>217 のソースの場合、a.Func<T>(); の時点で
a の型は T によらず決定しているから、Func が
テンプレートであることはコンパイラでわかるはずだが。
>>220 FAQ type_info::name()の結果は実装依存。
>>225 構文解析時には文法知識だけでやっていて、他のクラスがどうなってるか、
なんてことまでは考えていないのでは?
>>227 C++ はそれで済むような文法にはなってない。
例えば
std::string * x;
が"typename"無しでも(掛け算ではなく)変数宣言として扱われるのは、
それより前でstd::stringがクラス名として宣言されてることを
コンパイラが知っているからだし、あるいは上の例で
A a;
a.Func<std::string>();
なら"template"無しでも通るのは、(<が不等号なのではなく) a.Func が
メンバ関数テンプレートであることをコンパイラが知っている、からだ。
>>217、Comeau C++ なら通るからgccのバグだと思う。
Comeauも万能ではない
tvmetと
boost::ublasの
違いを簡単に教えてくれー。
とりあえず、ライセンス読んだり、インストールとかめんどいんで
boost::ublasつかってますけど。
232 :
デフォルトの名無しさん:03/04/09 13:58
すいません。誰か教えてください。
ユニコードファイルを読み込みたいのですが、
wstringのgetlineを使っても、うまく改行を認識してくれないらしく、
2行目以降が読み込めません。
そのファイルの改行コードは、0x0d 0x00 0x0a 0x00 なんですが、
これを認識して正しくgetlineするにはどうしたらいいでしょうか。
>>232 STLは何使ってんの
とりあえずVC++に付属のSTLはwchar_tの改行処理にバグがある
そうです。VC++.netを使っています。
バグがあるって…パッチとか出ていないんですかねぇ。
>>236 STLはソース状態で公開されてるんだから自分で修正すればいいじゃん。
>>231 tvmet の Usage を読んでたら、Introduction に
> "Tiny" means dimension less than about 10.
と書いてあるので、それ以上の次元を扱う場合には tvmet は使えないかも。
その分パフォーマンスとか記述の簡便さなんかが期待できるけど、
ublas と比べてる Benchmark は見付けれなかっし、俺にはどっちも
変態的なコードに見える。ライセンスは GPL なんで、利用は制限される。
boost::ublas は Fortran で書かれた BLAS というのが元になっていて、
相当の機能は実装しているようなので、これと同じように扱えると思う。
tvmet のウリが良く分かんないな…。機能も ublas の方が多いように思うけど
数学に疎いのでちょっと分からんです。俺なら boost::ublas かなぁ、
どうせ boost 入れるんだし…。
…こんなんで参考になる?(;´Д`)
>>238 thx
GPL->LPGL
かなりでっかくのってましたね。
でも、結局LPGLでもめんどいんで、やめました。
あと、boost::ublasにcross_product(外積のvector版)欲しかったんですがないようなんで(outer_prodだとマトリクスがかえる、、、)、
簡単な3D演算程度しか使用しないので、結局自分のうんこライブラリ使うことにしますた。
ていうか、次回からはクオータニン使おう。。。boostにはいってるし。
ちなみにわたしも数学疎いです。
quoternion…これはイイかもしれない。3D の演算用なんだろうか…覚えておこう。
サンクス。
fstreamみたいなfvectorって既存のライブラリでありませんか?
class(struct)はfstream::read,writeでファイルにデータメンバのみ
保存・ファイルから読み取りするような香具師なんですが。
std::ostream_iteratorとかその周りを調べれ
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class line_iterator
{
istream*in;
stringline;
boolis_valid;
voidread(){if(*in)
getline(*in, line);
is_valid = (*in) ? true : false;}
public:
typedef input_iterator_tagiterator_category;
typedef stringvalue_type;
typedef ptrdiff_tdiffrence_type;
typedef const string*pointer;
typedef const string&reference;
line_iterator() : in(&cin), is_valid(false){}
line_iterator(istream& s) : in(&s){read();}
reference operator*(){return line;}
pointer operator->(){return &line;}
line_iterator operator++(int){line_iterator tmp = *this;read();return tmp;}
bool operator==(const line_iterator& i) const{return (in == i.in && is_valid == i.is_valid) || (is_valid == false && i.is_valid == false);}
bool operator!=(const line_iterator& i) const{return !(*this == i);}
};
int main()
{
line_iterator iter(cin);
line_iterator end_of_file;
vector<string> V(iter, end_of_file);
sort(V.begin(), V.end());
copy(V.begin(), V.end(), ostream_iterator<string>(cout, "\n"));
return 0;
}
これってVC7だと
d:\VS.NET\Vc7\include\vector(109): error C2665: 'std::_Iter_cat' : 12 の
オーバーロードは 1 番目の引数を 'line_iterator' から要求の型に変換できません。
って出るんですけど、何かおかしいところありますか?
line_iteratorがiteratorの派生クラスでないのにはわけがあるの?
>>242 えーと、ランダムアクセスしたいのですけれども。
自作しないと無理ですかね。
Windowsならメモリマップドファイルをラップすれば簡単にできそうだけどね。
ごめん、そういうのはみたことない。
>>246 fstreamはランダムアクセスできるじゃん。
>>245 Generic本の最初の例なので意図は不明です。
251 :
デフォルトの名無しさん:03/04/11 12:33
前スレでStlPortのライセンスがアレなのによく使う気になるな、みたいな発言があったがものの見事に
放置されてるので非常に気になる。
どうアレなんでしょうか?
>>251 俺のつたない英語力では別に問題なさそうだったよ。
>>251 ケースバイケース
場合によっては使えるし場合によっては使えない。
そんなレスが何の参考になるのかと小一時間(ry
> This material is provided "as is", with absolutely no warranty
> expressed or implied. Any use is at your own risk.
…だよね。別に問題ないと思うけど。
元の発言者は「フリーウェアを使うのはダメだ」とかいう人なんじゃない?笑
なんかアメリカの特許がどーのって書かれてるくだりとかって、どうもアレだよねとかいわれると
そうかな?と思ってしまわないでもないです。
ところでstlport使用の際にドキュメントとかに使用してますみたいな旨は書かなくてよろしいんですかね?
ほんとソフトウェアの使用許諾書とかライセンスって長々とかいてあっていや。
stlportは1ページと短いけどさ。
とりあえず筆頭は爺…
等と言って信者を呼ぶのはやめておこう。
258 :
デフォルトの名無しさん:03/04/12 01:05
VC++6.0,WindowsXPです。
以下のようなコードでコンパイルエラーがでます。
#include <map>
class CTest {
std::map<int, CTest> m_map;
};
int main() {
return 0;
}
vc98\include\utility(26) : error C2079: 'second' が 未定義の class 'CTest' で使用されています。
vc98\include\xtree(28) : コンパイルされたクラスのテンプレートのインスタンス化 'std::pair<int const ,class CTest>' の参照を確認してください
vc98\include\map(46) : コンパイルされたクラスのテンプレートのインスタンス化 'std::_Tree<int,struct std::pair<int const ,class CTest>,
struct std::map<int,class CTest,struct std::less<int>,class std::allocator<class CTest> >::_Kfn,struct std::less<int>,
class std::allocator<class CTest> >' の参照を確認してください
My Documents\test\test.cpp(4) : コンパイルされたクラスのテンプレートのインスタンス化 'std::map<int,class CTest,struct std::less<int>,
class std::allocator<class CTest> >' の参照を確認してください
map<int, CTest*> とするとエラーは出なくなります。
自分自身のクラスを map に直接格納することはできないのですか?
>>258 コピーコンストラクタが定義されてないからじゃないの?
めんどかったら参照(&)入れとけ。
class CTest {
std::map<int, CTest&> m_map;
};
と、言ってみる。
>>259 コピーコンストラクタを明示的に定義しても同じエラーが出ます。
参照を入れるとまた別のコンパイルエラーが大量に出てきます。
参照をコンテナに格納することはできないと聞いているのですが。
>>260 コンテナをインスタンス化するためのテンプレートパラメータの型がまだ完成して無いから無理じゃない?
vectorは実装によってはポインタしか使わないから可能だね。
すまん、できんかった。
ところで、クラスのインスタンスを直接コンテナにぶち込むのはどうかと思うが・・・。
普通はポインタいれない?
>>263 ふつうは 258 のエラーでわかる。
そうでなくてもエラーメッセージの出てるソース見ればたいていわかる。
vc98\include\utility の 26 行目を見てみてはどうか?
>>263 boost::shared_ptr をぶち込むぱなしです。めんどくさいときや、コピーが気にならないときはオブジェクト格納してますが。
エラーメッセージは慣れかな?
>>264 そうですか…精進します。
とりあえず vc98\include\utility とかいろいろ見て考えてみます。
皆様ありがとうございました。要はもっと勉強しろってことですね。
267 :
デフォルトの名無しさん:03/04/12 05:45
>>258 mapの実装に依るけど、もしmapのオブジェクト自体に
ルートノードが入っていて、その中にCTestが直接
入っていたら、m_map.root.data<CTest>というような
構造になって引っかかる、ということでは?
268 :
デフォルトの名無しさん:03/04/12 05:53
>>267 単純に大きさが確定してないオブジェクトを入れようとしてるからだろ。
>>258 VC6+STLport、WinXP で何の問題もなくコンパイルできたわけだが。
たぶんVCのSTLが腐ってる。
CTest().m_map[0].m_map[1].m_map[2].m_...
>>267 > mapのオブジェクト自体にルートノードが入っていて
んなわけねぇだろ。
>>272 そうか?効率は置いておくとしても、
template <class X, class Y>
struct MapNode {
int flags;
X mid_index;
MapNode *left;
MapNode *right;
Y leaf_value; /* might be uninitialized */
};
なんて実装は考えられないか?
>>273 何のメリットも無いな。
考えられない。
もちつけ
ってか、ここの人って反論されると
いきなりキレる人多いよね。
多分一部の人だけだと思うけど。
やっぱり、
な け な し の プ ラ イ ド を 壊 さ れ る
のがいやなのかな(w
>>276 >反論されると いきなりキレる人多いよね。
そんなのどこのスレでも同じようなもんだろ
>>277 確かに荒れてないスレの方が少ない罠。
見ててそんな印象をもっただけ。
まぁ、漏れの勘違いなら構わないんだが。
キレる奴と煽る奴、それが2ch。
276は煽る奴
281 :
デフォルトの名無しさん:03/04/15 04:45
charの配列を、vector<char>にそのまま代入したいのですが、
現在は下のように一つずつ代入する方法で行っています。
char buf[10000];
vector<char> v;
v.resize(10000);
for (int i = 0; i < 10000; i++) v[i] = buf[i];
ただ、この方法では配列の数が増えたときにすごい重いので、
もっと簡潔な方法がありませんでしょうか。
vector<char> v( &buf[0] , &buf[10000] );
>>281 > 配列の数が増えたときにすごい重いので、
ホントに計った?
forのところの
i++ → ++i
にしてみる。
最適化されたらいっしょになるかな?
>>281 vector<char> v( &buf[0] , &buf[9999] );なのでは?
>>281 iteratorとcopyを使ってみては?
g++ 3.2だと-O3しても倍以上速いね。
>>285 STLでは終端は末尾のひとつ後ろを指定します
charをintにする。
template< typename T, std::size_t N >
inline void arrcpy( std::vector<T>& target, T const (&source)[N] )
{
target.resize( N );
std::memcpy( &target[0], source, N );
}
>>281 どうよ?
>>290 ×std::memcpy( &target[0], source, N );
○std::memcpy( &target[0], source, sizeof(T)*N );
ダロ?
294 :
デフォルトの名無しさん:03/04/16 00:00
>>292 そうそう。よくあるバグ。
スレとあんま関係ないけどさ、
このサイズ忘れるの防止できないかね。
今までこれ系のバグで開発止まった事何回もある・・。
295 :
デフォルトの名無しさん:03/04/16 01:14
なにこれ。
簡単に言うと boost ショボイ版みたいな感じですかねぇ。
>>294 memcpyなんて使わないからいい。
target.assign( &source[0] , &source[N] );
>>299 テンプレートでないところでstatic_assertって必要になる?
(^^)
>>300 うーん、あんまないかも…遊びで作ってただけなんで。型のサイズチェックとかかなぁ。
gcc 限定で、const_cast とか…これぐらいしか思い付かん(;´Д`)Cスレの方が良かったかな。
#define CONST_CAST(__type, __p_instance) \
__extension__({ \
typeof(__p_instance) __instance = __p_instance; \
STATIC_ASSERT( \
__builtin_types_compatible_p(const __type, typeof(__instance)) \
); \
(__type)(__instance); \
})
303 :
デフォルトの名無しさん:03/04/18 12:16
std::stringからdoubleやintに変換したい場合、スマートな方法はないでしょうか?
boost::轢死cal_cast
>>303 それか、std::stringstreamを使って組む。
boost::歴史cal_castは内部的にはこれを使っている。
>>304 vc6でエラーでるからって轢死はないだろw
vc7でもwarning出るしな
>>308 見た。 いらね。
STLのvector使っとけ。
>>308 漏れも見た。
・配列拡張にrealloc→operator=の定義によっては誤動作
・新しく取得したメモリにmemset(0)→vtableが死んでる
・例外安全でない
・constを正しく使っていない
いらね。っていうかダメダメ。
∧_∧
( ^^ )< ぬるぽ(^^)
∧_∧
( ^^ )< ぬるぽ(^^)
なんか前の山崎渉の方がよかった...
激しく同意
(^^)
↑山「埼」渉かよ!
山埼渉カコイイ
DOS窓のプロパティで設定できました。
command.com /E:1024、という風にしてもできるようですね。
ありがとうございます。
Loki::AssocVector::insertAssocVector っておかしくねーか?
↓
iterator insert(iterator pos, const value_type& val)
{
if (pos != end() && operator()(*pos, val) &&
(pos == end() - 1 ||
!operator()(val, pos[1]) &&
operator()(pos[1], val)))
{
return Base::insert(pos, val);
}
return insert(val).first;
}
323 :
デフォルトの名無しさん:03/04/25 22:31
vc6 stlport でboost::numeric::interval って使えないの?
cmath系がstd::hoge でエラーでて動かないし、
他にもエラーでまくり。
>std::hoge
using std::hoge;
_STLP_NO_なんちゃらでstd::をグローバルネームスペースに変換しちまえばいいんだが
そうすると、今度はiostreamのほうでひっかかるという罠。
325 :
STL初心者 ◆Saqno3S4wc :03/04/25 23:39
VC6にStlPortを入れたのですが
StlPortのStlを使ってコンパイルされていることを
確かめる方法はありませんか?
>>322 変かなあ
posが指す位置と入れる値によっっちゃ順序が狂うが...
これっていかんの?
>>325 コンパイルされたバイナリがSTLport使ってるかどうかか?
シンボル見ればなんとなくわかるんでないかい?
STLportをincludeしてるかどうかの判別をしたいなら、
#if defined(_STLPORT_VERSION) でいけるはず
>>327 報告めちゃ遅ですみません。
STLPortが使えているようです。
ありがとうございました。
lokiはマニアックすぎて使ってないや。
STLportとboostで満腹
boostも最近マニアックネタが多いと思うが。spiritとか
332 :
デフォルトの名無しさん:03/04/28 19:22
>>329 stlport とは食べ合わせよくないです。
でもシングルトンはつかわさせていただいてます。
つくるのもめんどいし。
>>329 前スレにも出てた。ずっと前から既出。
Loki は多少マニアックかもしれないが、使いやすいし
コードは STL の何十倍も読みやすい。
強力な Functor と Singleton は手放せないね。
Loki で一番難しいのは、強力な TypeList をどう使うかということだと思う。
> 強力な Functor と Singleton は手放せないね。
boost じゃダメなの?
Lokiで重宝してるのはSmartPtrだな~。
>>334 boostにsingletonなんてあった?
VS2002では問題なく使えてて
STLportをVS2003で使いたいんやけど
ヘッダーのどこを変えればいいの?
Functorkon今度つかってみよ。
この前、factory使って簡単だなぁって思ったんで。
341 :
デフォルトの名無しさん:03/05/08 22:49
342 :
デフォルトの名無しさん:03/05/11 08:26
もうみんな飽きたの?
343 :
デフォルトの名無しさん:03/05/11 11:06
boost::shared_ptrとlokiのsmart_ptrはどう違うんですが?
基本的に同じで両方とも循環参照には対応していないという事でいいんでしょうか?
相談です。
boost::lambdaで、構造体の内部変数にアクセスすることはできないでしょうか。
具体的には
map<int, int> m;
for_each(m.begin(), m.end(), cout << (_1.first));
みたいなことをやりたいのですが…。
当然、上のソースをコンパイルすると_1はplaceholderクラスなので、そんなメンバは存在しないとエラーが出ます。
俺はこうやってやっている、という例はありませんでしょうか?
(目的だけ考えればoperator <<なりを実装すればいいんですが、lambdaがとても便利なので他にも使える汎用的な書き方が欲しいと思いまして…)
(&_1)->first
これどうですか?(未確認)
その書き方では無理でしたが、試すうちにこれで通りました。
bind(&pair<const int, int>::first, _1)
constを忘れていたがために6時間を無駄にしました…アイタタ。
348 :
デフォルトの名無しさん:03/05/16 00:35
以下のようなコードでVisualC++だと(*1)の箇所でテンプレートの
インスタンス化云々のエラーが出ます。gccでは出ません。
こういうもどかしさを解消する流儀はないでしょうか。
class type1;
class type2;
template <typename T> struct type_selector;
struct type_selector<tag1> { typedef type1 type; };
struct type_selector<tag2> { typedef type2 type; };
template <typename T>
class derived : public type_selector<T>::type { // (*1)
...
};
>>348 template <typename T> struct type_selector{ typedef dummy type; }
としたら通ったぞ
>>349 むひょー!素晴らC。こんなテクが知りたかったんです。
どうもありがとう。
ポイントは dummy に型が未確定のものを指定することですね。
(組み込み型や既に確定している型を指定した場合は駄目でした。)
おいらは
template <typename T> struct type_selector{ typedef T type; }
ってしました。
C++のtemplateって中途半端な気が。
//2つの文字列の比較
equal<"hoge", "hoge">::is_valid
//浮動小数点のtemplateパラメータ
log10<123.456>::value
//文字列を出力
md5<__FILE__ __LINE__ __TIME__>::value
みたいな事ができて、
あと、プリプロセッサマクロで乱数生成できたらうれしいのに。
なにいってんのかわかんないけど
template<class T> inline bool equal(const T *a, const T *b) { return !strcmp(a, b); }
でいいんでないの?
コンパイル時に解決したいならlokiあたりをよく読んでみれ。
回りくどいとか見た目がわかりづらいというなら話が変わるが。
> あと、プリプロセッサマクロで乱数生成できたらうれしいのに。
ここは template スレですが?…と一応突っ込みを入れておくとして、
boost::preprocessor を使えば多分乱数作れるよ、やったことないけど。
あと tempalte の使い方がキモイ。ていうか意味分かんね。
354 :
デフォルトの名無しさん:03/05/16 20:23
初歩的な質問ですが、templateって、宣言部と実装部を分けたり出来ないのでしょうか?
template関数作りましたが、長いので実装部を.cppファイルに移動したいのですが。
>>354 .cppファイルに移動した後、それを .h 内でインクルードしる。
>>355 そのやり方しかできないVCがキモクテいやだ。
でもVC楽だ・・・。
VCでうまいやり勝たなかったっけ?
互換性に影響のない拡張ならそのうち標準に準拠するさ。
きっと。
あるいは、明示的なインスタンス生成。
361 :
デフォルトの名無しさん:03/05/18 09:02
生配列の要素数を定数式で表現するための関数テンプレートを思いついた。
とりあえず、gccでは通る。
けど、名前が思いつかない。
だれかいい名前つけてやって。
#include <cstddef>
template< typename T , std::size_t N >
char const ( &xxxxx( T (&)[N] ) )[N];
int const array[] = { 436,346,23,0,58,5678,32,0,4573 };
struct X
{
static std::size_t const num_elements = sizeof( xxxxx( array ) );
};
362 :
動画直リン:03/05/18 09:11
>>361 最後に sizeof 取る部分まで含めて、LENGTH とか lengthof とか
いうマクロにして使ってる人が多いと思う。
template プログラミングのキモは遅延コンパイルにあると思うのだがどうか。
>>367 お、3ヶ月越しのデジャブかよ。
だが、宣言のキモさで一歩リードしてる。
ト、イウコトニシタイノデス。
━―━―━―━―━―━―━―━―━[JR山崎駅(^^)]━―━―━―━―━―━―━―━―━―
あげ
372 :
デフォルトの名無しさん:03/05/28 12:21
char型の二次元配列buf[256][256]の
配列vectorを宣言するやり方がわかりません。
373 :
デフォルトの名無しさん:03/05/28 15:16
保守
std::vector<std::vector<char> > buf(256, std::vector<char>(256));
>>372 class buf
{
char value[256][256];
public:
typedef char type[256];
operator type*(){ return value; }
};
std::vector< buf > a;
>char型の二次元配列buf[256][256]の配列vector
3次元配列のvector?
4次元配列?
378 :
デフォルトの名無しさん:03/06/05 09:19
言語依存の問題ヲ一つ:
template<class T>struct NonPointer
{ typedef T non_pointer; };
template<class T>struct NonPointer<T*>
{ typedef T non_pointer; };
これヲVC7で表現できないかなー?
>>378 それってVC7.1じゃ駄目なの?
おれのはVC6だから当然無理だけど。
あと、VC6だとtemplate引数にint値が使えないのが痛い。
>>379 class じゃなくて typename つかえばいいじゃんとかじゃなくて?
>>380 379じゃねーが、VC6だと↓が困ったことになる、って話かと。
#include<iostream>
template<int N> void f() {std::cout << N << std::endl;}
int main() {
f<1>(); f<2>(); f<3>();
}
>>381 intじゃなくても関数の明示的な特殊化は軒並みダメだよ
383 :
デフォルトの名無しさん:03/06/08 08:40
スマン、単語を間違えた
特殊化じゃなくてインスタンス化だた
385 :
デフォルトの名無しさん:03/06/14 00:08
おれっちのfunctionをけなして
namespace FN
{
namespace IN
{
class Null{};
template<
typename R,
typename T1 = Null,
typename T2 = Null,
typename T3 = Null
>struct fnimp{ typedef R (*pf)(T1,T2,T3); };
386 :
デフォルトの名無しさん:03/06/14 00:08
template<
typename R,
typename T1,
typename T2
>struct fnimp<R,T1,T2,Null>
{ typedef R (*pf)(T1,T2); };
template<
typename R,
typename T1
>struct fnimp<R,T1,Null,Null>
{ typedef R (*pf)(T1); };
template<
typename R
>struct fnimp<R,Null,Null,Null>
{ typedef R (*pf)(); };
}
template<
typename R,
typename T1 = IN::Null,
typename T2 = IN::Null,
typename T3 = IN::Null
387 :
デフォルトの名無しさん:03/06/14 00:09
>struct function
{
typedef typename IN::fnimp<R,T1,T2,T3>::pf pf;
function(pf p) : pt(p){}
R operator () (T1 t1,T2 t2,T3 t3){ return pt(t1,t2,t3); }
R operator () (T1 t1,T2 t2) { return pt(t1,t2); }
R operator () (T1 t1) { return pt(t1); }
R operator () () { return pt(); }
private:
pf pt;
};
}
ネストの深いifブロックをおもいだすな
ちょっと質問です。えらい人教えて。
半年ほど前に、エンディアンの変更をするテンプレート関数を作った。
namespace detail{
template< size_t Distance>
struct byte_swap {
static void do_swap( byte *x) {
std::swap( *x, *( x + Distance));
byte_swap< Distance - 2 >::do_swap( x + 1);
}
};
template<>
struct byte_swap< 1 > {
static void do_swap( byte *x) {
std::swap( *x, *( x + 1));
}
};
template<>
struct byte_swap< 0 > {
static void do_swap( byte *x) {}
};
}
template< typename T >
inline void swap_endian( T &x){
detail::byte_swap< sizeof( T ) - 1 >::do_swap( reinterpret_cast< byte *>( &x));
}
こんな感じ。で、エンディアンの異なるファイルを構造体で一括して読み込んでから
各メンバをスワップさせたいんですが、いちいち各メンバにswap_endian( a.first);
のように書くのがアホくさいんです。構造体のメンバにforeach見たいにアクセスする
方法ってないでしょうか?実行時はできないだろうけど、コンパイル時にやれないことも
ないんじゃないかと思うんだけど、まったくわかんない。
struct Nil{};
template <class A,class B=Nil> struct TL{ typedef A head; typedef B tail; };
template <class TL> struct Tuple : public Tuple<typename TL::tail>{
typename TL::head a;
template <class Fun> void each(Fun f){
f(a);
Tuple<typename TL::tail>::each(f);
}
};
template <> struct Tuple<Nil>{
template <class Fun> void each(Fun f){}
};
struct Printer{
template <class T> void operator()(T val){
std::cout<<typeid(T).name()<<" "<<val<<std::endl;
}
};
Tuple<TL<int,TL<short,TL<char> > > > tuple;
tuple.each(Printer());
タプルの要素を順に書き出します。
構造体をタプルで作れば同じように、メンバに順にアクセスできます。
普通の構造体のメンバ変数のforeachは不可能と思われます。
>>391 ありがとうございます。
おとなしく、ひとつずつ手書きすることにします。やっぱむりかー
394 :
デフォルトの名無しさん:03/06/18 21:40
>>391 Tuple個人的には気に入りましたがこれでは無理かと。
構造体のサイズって一定じゃない(アライメント調整すれば別だけど)
struct temp{char , int };
これで話せば、Tupleでトレースするには、
sizeofで場所を突き止めるんだよね。(なまえ使えないから)
charの場所(&temp)のつぎはint。場所は(&temp+1)ここじゃなから
swapなんてとんでもない。間違っていたらごめん。
>>393 自分が、タプルのことがよくわかっていない屁たれということがひとつ。
あと、目的の構造体を使ったライブラリがすでにあるんで、
タプルはやめておきます。
396 :
デフォルトの名無しさん:03/06/18 22:21
巡回参照問題を解決したスマートポインタを誰かが作っていたような記憶があるのですが、
どこかに置いてないか知っている人いますか?
自分で作ろうと思ったら意外と難しいな・・・・
397 :
デフォルトの名無しさん:03/06/18 22:22
>>396 俺もホスィ。
もし見つけたらこのスレに貼ってくれ、頼む。
GC無しで実現出来ればかなり使えるジャン。
>>396 循環参照問題を解決ってことは参照カウントではない手法なんだろうけど、
GCを行うメモリ管理方式?
それとも参照カウントと弱参照の組み合わせ(boostのshared_ptrとweak_ptr)?
400 :
デフォルトの名無しさん:03/06/18 23:07
402 :
デフォルトの名無しさん:03/06/19 09:12
>>396 lokiのスマートポインタって解決してなかったけ?
ところで、vc6,stlportで
std::string hoge("hoge");
std::string moe( hoge.begin(), hoge.end );
を、/MD /MDd のオプションでビルドすると、
error LNK2001: 外部シンボル ""__declspec(dllimport) public: __thiscall _STL::basic_string< ・・・略
は未解決です。test.exe : fatal error LNK1120: 外部参照 1 が未解決です。
stlportのライブラリのビルドに失敗してる?
それ以外のオプションならきちんとビルドできるのにな・・・。
_STLP_DEBUG
消したらとおった・・・。
デバッグモードoffにしろということか・・・。
>>402 ライブラリをビルドしたときには_STLP_DEBUGが付いてなかったんだろう。
405 :
デフォルトの名無しさん:03/06/19 14:50
stlのsetとかmapって二分木ですよね。
これらに要素を追加して、その内容をファイルにセーブする場合、
begin()~end()の順でセーブして、読み込むときにinsert()で追加していくと
読み込んだ後のsetとかの検索速度は悪くなりますか?
悪くなる場合、検索速度の改善方法は一般的にはどのような方法がありますか?
406 :
デフォルトの名無しさん:03/06/19 16:22
↓のようにコンテナはpublicで継承して使っても
よろしいのでしょうか?
struct Person{
int Age;
string Name;
};
class Community : public std::list<Person*> {
...
};
/D "_STLP_DEBUG"
で stlportビルドしてみたけど、ダメポですた。凄い人、教えてー。
>>406 stlのコンテナは継承してはいけないはず。
効率を上げるため、仮想デストラクタがないから(確かめたことないけど)。
>405
ただの二分木はあまりつかわない。
赤黒木あたりで実装されることが多いので、効率は悪くならない。
>>405 二分木といってもAVL木か赤黒木なんかで挿入と同時に平衡処理をしてるはずなので大丈夫かと
>>408,409
普通は二分木ではなく赤黒木(勉強不足でよく知りませんが)で
心配無用なのですね。サンクス
411 :
デフォルトの名無しさん:03/06/19 20:51
>>406 Community* commp = new Community;
こういう事しなければよろしいかと
>>411 それは別にいいんじゃないですか?
いけないのは↓こういうことをしたときですよね。
std::list<Person*> *p=new Community;
delete p;
>>406 is-aの関係よりhas-a関係にしたほうがいいと言われると思います。
レスありがとうございます。
has-aの関係にします。
414 :
デフォルトの名無しさん:03/06/19 22:13
>>401 >>402 どうもです、とりあえず一つあたってみたのですがソースが読めない・・・
どういうアイディアを使ってどういう構造になっているのでしょうね、難しい。
この問題は簡単に解決とは絶対にできなさそうですね、週末また頭ひねって考えよう
ところで、巷で良いという噂の Modern C++ Design には、このアルゴリズムが載っていないか知りませんか?
本屋に無いので注文せざるを得ないのですが、注文して載ってなかったらとても悲しいので。
415 :
デフォルトの名無しさん:03/06/20 01:03
>>412 すみません。おれが書き込みミスってた。(ミスりすぎ)
std::listはvirtualなデストラクタ持ってないってことですね。
補足してちょっとミエはってみたり。
>>414 > どうもです、とりあえず一つあたってみたのですがソースが読めない・・・
覚えてないが、どれも基本的に Mark and Sweep だったような。
あと、Loki / Modern C++ Design には循環参照があっても使えるような
スマートポインタは含まれてないぞ。あのフレームワークを使って
実現することは出来るだろうが…。
417 :
デフォルトの名無しさん:03/06/26 11:12
>402
シンボルの未解決というのは、ライブラリをリンクしてないからでは?
418 :
デフォルトの名無しさん:03/06/26 14:11
vcのstlportがヘボイからです。
vcってdinkumじゃなくてstlportになったの?
STLPortはコンパイラオプションでwchar_tの扱いが違うだけでリンクできないんだよなぁ・・・
VC++のデフォのSTLはどうやって解決してんだ?
421 :
デフォルトの名無しさん:03/06/26 23:04
質問です。テンプレートを使うのは今日が初めてです。
template <class T> class A{
T data;
}
A<int> x;
A<CFile> y;
としたとき、xやyからテンプレート型名を取得する事はできないでしょうか?
つまり、ここでいうintやCFileのことです。
x::Tとできればいいのですが、できませんでした。(VC++.NETにて)
(もちろん、変数名があればテンプレートの型名は一意に決まるとは思うけど、マクロに使いたいから。型を変更するとき何カ所も変更する仕様にしたくないし、型を気にしなくていいマクロにしたいのです。)
>>421 それは今のテンプレート仕様の欠点。
だからtypeofの導入が強く求められてる。
テンプレート関数の引数に渡せば型は得られるがその関数内部でしか使えないので特定用途に限られる。
template< typename T > void func( T a )
{
// func に x を渡せば、T は A< T >、y を渡せば A<CFile>
}
>>421 どんなマクロを目論んでるんだろ。
templateだけじゃ実現できないようなことなの?
>>422 そうですか・・・。やはり、マクロに型名を毎回埋め込む事にします。
>>423 #define PROPERTY(classname, propget, proplet) \
classname.PropertyGetHandler = (classname::ktype (*)(void*))(propget);\
classname.PropertyLetHandler = (classname::ktype (*)(void*, classname::ktype))(proplet);\
classname.Parent = this
としたかったんです。
実装は
ktype (*PropertyGetHandler)(void *Parent);
operator ktype(){
KTASSERT_C(PropertyGetHandler, "書き込み専用プロパティを読み込もうとしました。");
return PropertyGetHandler(Parent);
}
てな感じで(Getのみ書いてます)。クラスのコンストラクタでPROPERTY(Width, GetWidth, SetWidth)と書いておけば、
n = Width;なら、現在の幅を取得、
Width = n;なら、現在の幅を設定、
とできるので、分かりやすくていいかな、と。
単にメンバとして実装しないのは、カプセル化のためですが、カプセル化されてないように見えてカプセル化されてるってのがおもしろい・・・って思っただけで。まぁ、GetWidth()・SetWidth()って普通にすればいいんだけどね・・・。
まぁ、マクロに型名埋め込む事にしますわ。
425 :
名無しさん@Linuxザウルス:03/06/26 23:35
>>424 templateだけで実現できそうな気がするな
まあマクロなしだとthisを渡すのは消せないが。
いま考えたら、void *Parentもテンプレートにしちゃえばキャストが要らなくなってマクロが簡単になりますね。
でも、それだと、
CProp<int>Left;
CProp<int>Right;
CProp<int>Top;
が、
CProp<CWin, int>Left;
CProp<CWin, int>Right;
CProp<CWin, int>Top;
に成っちゃう・・・(CWinはこのプロパティを持っているクラスの名称)けどこれは仕方ないかな。
>>426 こんなの書いてみた
template<typename T> class Setter {
T& val_;
public:
Setter(T& v):val_(v){}
void operator()(T v) {val_=v;}
};
template<typename T> class ReadOnlySetter {
public:
ReadOnlySetter(){}
ReadOnlySetter(T&){}
void operator()(T v) {std::cout << "read only property assignment" << s
td::endl;}
};
template<typename T> class Getter {
const T& val_;
public:
Getter(const T& v):val_(v){}
T operator()() {return val_;}
};
template<typename T, typename S = Setter<T>, typename G = Getter<T> > class Prop
{
S set_;
G get_;
public:
Prop(S s, G g) :set_(s) ,get_(g) {}
Prop(T& v) :set_(v) ,get_(v) {}
const T& operator =( const T& newval ) { set_(newval); return newval; }
operator T() { return get_(); }
};
使用例
class Frame {
int width_;
int readonly1_;
class GetReadOnly2 {
const int& s_;
public:
GetReadOnly2(int& s):s_(s){}
int operator()(){ return s_*2; }
};
public:
Prop<int> Width;
Prop<int, ReadOnlySetter<int> > ReadOnly1;
Prop<int, ReadOnlySetter<int>, GetReadOnly2> ReadOnly2;
Frame()
:width_(0)
,readonly1_(1)
,Width(width_)
,ReadOnly1(readonly1_)
//,ReadOnly2(ReadOnlySetter<int>(), GetReadOnly2(readonly1_))
,ReadOnly2(readonly1_)
{}
};
テンプレート使いすぎるともうどんどんメタ言語のようになっていくな
>>428は
Frame f;としたときに
f.Width でf.width_を読み書き
f.ReadOnly1 で代入は阻止、読むと readonly1_が読める
f.ReadOnly2 も代入は阻止、読むと readonly1_ * 2 が得られる
てなかんじ
初歩的だけど(^^;
getterとsetterにそれぞれ関数オブジェクトを渡すことでいろいろできると。
#include "boost/function.hpp"
template< typename ValueType >
class property
{
public:
typedef ValueType value_type;
typedef boost::function< value_type () > getter_type;
typedef boost::function< void ( value_type const& ) > setter_type;
explicit property( getter_type const& g , setter_type const& s ) : m_getter( g ) , m_setter( s ) {}
explicit property( getter_type const& g ) : m_getter( g ) {}
operator value_type () const { return m_getter(); }
property& operator = ( value_type const& rhs ){ m_setter( rhs ); return *this; }
private:
getter_type const m_getter;
setter_type const m_setter;
};
#include <iostream>
#include "boost/bind.hpp"
class X
{
int m_x;
int get(){ std::cout << "get" << std::endl; return m_x; }
void set( int i ){ std::cout << "set " << i << std::endl; m_x = i; }
public:
property< int > p;
X() : p( boost::bind( &X::get , this ) , boost::bind( &X::set , this , _1 ) ) {}
};
int main()
{
X x;
x.p = 1;
std::cout << x.p << std::endl;
x.p = 100;
std::cout << x.p << std::endl;
return 0;
}
// ワーイ、boostサイコー
不要な部分を添削してみた。
struct X {
...
int p;
...
};
int main()
{
X x;
x.p = 1;
std::cout << x.p << std::endl;
x.p = 100;
std::cout << x.p << std::endl;
return 0;
}
434 :
デフォルトの名無しさん:03/06/27 13:04
435 :
デフォルトの名無しさん:03/06/27 15:08
>>432,431
最高にイかしてるけど、普通にXメンバーfunc、callした方が
イイ罠。
>>435 すべてのメンバ変数(属性)はアクセサを経由して使うって決めれば
統一感もあるし凝った細工も要らないね。
437 :
デフォルトの名無しさん:03/06/27 16:29
がーん・・・。operator=って継承できねぇ・・・。
438 :
デフォルトの名無しさん:03/06/27 17:05
operatorにstaticが使えないのしらなくて悩んだことあるな。
VC7のstd::vector::clearは持っている領域を解放して、reserveで設定した
容量も無効にしてくれるみたいなんですが、これは規格に合っている動作なんでしょうか?
swap技法みたいなのもありますし、erase(begin(), end())と同じだと思っていたんですけど……
解放されないのをあてにして書いたコードは書き換え無いと。
ちなみにVC6やgcc3はerase(begin(), end())を呼んでいるだけみたいです。
>>439 clear()したときに、領域をどのように開放するかは実装依存で、
swap技法を使えばどの実装でも解放されることになってる。
|ω・`) すいませんSwap技法てなんですか?
>>441 Effective C++からの一連の本嫁~
とにかく
v.swap( std::vector<int>() );
こんな調子で作っただけの一時オブジェクトと交換する手法
>>440 ということは、出来るだけ解放させたくない(これまでに確保した領域を
再利用したい)場合はclear()ではなくerase(begin(), end())を呼んだ方が
いいってことですね。
>>441 EffectiveSTL 第17項 余分な容量を取り除くには「swap技法」を使おう
を参照のこと。
>>443 規格を見たら clear()は erase(begin(), end())と同じと、
書いてありました。ちゃんと見ずに言ってスマソ。
結局、VCがそういう仕様である限り erase(begin(), end())
としたほうが良いのは、かわりないけど。
>>444 VC7.1のvectorは:
>void clear()
>{// erase all elements
>erase(begin(), end());
>}
になってますね。
標準コンテナにハッシュマップが載るのは
いつごろになりそうなんですか?
> clear()でcapacity()が変わってしまうのは
ごめん、↑は↓に置き換えて読んで。
> clear()でcapacity()が小さくなってしまうのは
>>445 え、マジで?
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\vector
は
void clear()
{// erase all
_Tidy();
}
になってるんだけど。
vector<int> a;
a.reserve(100);
cout << a.capacity() << endl;
a.clear();
cout << a.capacity() << endl;
も
100
0
になるんだけど。
直されてるバージョンがどこかにあるのかな。
>>449 よくみたら引用した行は vector<bool> でした。
通常版のvectorは確かに_Tidy()呼んでましたね。申し訳ない
>>450 了解っす。てことはまだ未修整ってことか……
自分で修正するか(w
452 :
デフォルトの名無しさん:03/07/06 03:04
>>442 だれもツッコミないから俺から一言。
そのような一時オブジェはswapには渡せません。
>>452 左右逆でしたね。正しくは
std::vector<int>().swap(v);
しかし間違っているというだけで正しいものを指摘しないのはなんだか。
454 :
デフォルトの名無しさん:03/07/06 05:32
いけずぅ~♥
455 :
デフォルトの名無しさん:03/07/07 23:23
457 :
デフォルトの名無しさん:03/07/08 00:17
>>456 やっぱダメだよね。
特別なコンパイラでもあるのかと、思っちゃいましたよ。
13章4.1のどこでデフォルトテンプレート引数に関数使ってんの?
>>458 ごめんごめん。質問わるかった。
デフォルトテンプレートに関数ではなく。
int test(){}
template<int (*pf)() = test> これではなく。
struct fun{};
関数のテンプレートにデフォルトを持たすことができないよね?といってるんですよ。
template<typename T,class C = Cmp<T> > ←これ。
int compare(const String<T>& s1,const String<T>& s2){}
こんなのない?
>>459 関数テンプレートはデフォルト引数を設定できないよん。
デフォルト引数を設定できるのはクラステンプレート。
関数テンプレートはその代わり使用される時のコンテキスト(引数)で
判断が可能な場合は引数の省略が可能。
(逆にクラステンプレートにこの機能はない。)
>>460 わざわざ詳しい説明に感謝。
俺は本のせいで数時間(数日?)、惑われてしまった。
もしかしたら。と、期待を胸に抱いて。
萌え萌えに語ることないか。
最近operator->*に萌え萌え
Dispatchオブジェクトのスマートポインタに
(pDisp->*L"Hoge")();
とか
俺は boost::spirit に萌え。
しかし忙しくてあまりいじる暇がない……
465 :
デフォルトの名無しさん:03/07/10 21:18
>>465 function<void()> operator->*( const wchar_t* name ) { ... }
とかじゃないの?
つーか確かに
>>463 の使い方は萌え萌えだ。
つーか、この使い方を書いてくれた
>>463に萌えだ。
>>463 もえ~~~~~。LV UP!
もえもえもえもえもえもえもえもえもえっ。
もえーーーーーーーー。ごっちゃんですぅ。
470 :
デフォルトの名無しさん:03/07/11 01:58
スマソ。漏れが低レベルなんだろうが
>>463の何が萌えなのかサパーリ分からん。
誰か説明してたもれ…
471 :
デフォルトの名無しさん:03/07/11 02:02
>>463 それぞれに違う引数を渡したい場合はどうするんだろう?
STLの利点が分からない…
誰か説明してちょ♪
>>474 はじめての恋。そして、別れ。
のような甘く、ちょっぴり切ない気持ち。
>>474 標準なので移植性が高く、使い方を間違わなければ効率もいい。
ものによってはCの標準ライブラリよりも効率がいいよ。
あと、汎用的なわりには結構使いやすいんではないかな。
>>474 C++使いなら誰でも書ける程度の代物が多いけれど、
* 標準なのでどこでも使えるし、
* (まともな実装を選べば)枯れてるからバグも少ないし、
* <vector>とか<map>とかalgorithm>とか、簡単ではあるけれどよく使うものなので
塵も積もれば山となるってことで最終的には結構手間を省けるし、
* C++使いなら誰でも(きっと)知ってるはずなので、
関数やクラスの名前だけ見ても、ぱっと見何をしてるのか推測しやすく、
ソースコードの可読性が上がる。
boostもそれに準じる。Lokiはまだちょっと知名度低そうだけど。
HEWにはSTLついてないのだが・・・
>>479 まあ標準に準拠できていない処理系は別問題(もはやC++として議論できない)
ってことで
HEWの準拠度はVC6よりはましだと思ったが。
ライブラリが無いのがつらい。
>>481 そんならSTLPortとか持ってくればいいんじゃない?
(VCで比較するなら2世代前のVC6ではなくVC7.1で比較して欲しい(笑))
そうだね。でも普通に考えてVC7.1には勝てないことはわかるしね。
STLportからは一部持ってきてつかってるよ。というか、参考にして適当なのでっちあげた。
SHでの開発にKPITのGCCが使えないか探り中。
VC6+STLport+boostでかなり助かった。
今お試しでVC7.1いんすこしたとこ。
485 :
デフォルトの名無しさん:03/07/13 04:58
以下のようなコードを
GCC3.2で使おうとすると、
template < typename T >
struct A
{ typedef T value_type; };
template < typename T >
struct B : public A< T >
{ void f( value_type t ){} };
以下のようなWarningがでました。
warning: `typename B<T>::value_type' is implicitly a typename
どうもB<T>の公開基底クラスであるA<T>でのtypedefが見えていないようです。
これはC++の仕様?それともGCCのバグ?
なにかうまい方法はないっすかね?
たんにどっちのvalue_typeって迷っているだけ
追加
A<T>::value_type or B<T>::value_type ?
{ void f( typename value_type t ){} };
nisurebaiinnjyanaikana?
>>486=487
すみません。よくわかりません。
B<T>であらたにtypedefは追加していないのですが、、、
>>488 それでよさそうな気もしますが、
こんどはその行で parse error がでます。
わけわからん、、
たんに選択してやればいいだけ
template<typename T>
struct L : public A<T>
{
typedef typename A<T>::value_type value_type;
void f(value_type t){}
};
もう一つ
template<typename T>
struct L : public A<T>
{
void f(typename L::value_type t){}
};
>>485 Aが特殊化されていたら A<T>::value_type が存在しない/型名でない可能性
があるのです。
>>490 >>491 ありがとうございます。
しかしですね、私としては
>>490のようなことをせずにすむように
struct Aを定義しているつもりなんですよ。
typedefを必要とするBのようなクラスがたくさんあるときに、
Aから継承するだけで、typedefを書かなくても済むように。
(つまりAをstd::iteratorのように使いたい。)
また、
>>491では
>>485と同じWarningがでます。
Warningの内容からすれば、
>>488の対処がマッチするような気がするのですが、
>>491ではなぜか parse error が出てしまうのです。
ちなみにこのコードでも同じことが起こります。
#include <iterator>
#include <iostream>
using namespace std;
template< typename T >
class B : public iterator< random_access_iterator_tag, T >
{
public:
void f( value_type a ){}
};
また、
void f( value_type a ){} を
void f( typename value_type a ){}
に変えるとparse errorが出る、というのも
>>485のコードと同じです。
>>493の訂正
誤
>>491ではなぜか parse error が出てしまうのです。
正
>>488ではなぜか parse error が出てしまうのです。
>>493 この場合にはtypename の次には少なくとも一つネームスペースとしてのクラス名
が必要なのです、と文法できまっています。よって
typename A<T>::value_type t または
typename B::value_type
とかけばよいです(
>>491は通るよね?)。
自分も同じ事でハァって思って結局警告を無視するかいちいち継承先で
typedef typename ....
って書くしかないという結論になりました。後者だとstd::iteratorの存在意義
があまりない罠。
実はVC++でテストしたら警告が出ないんだよね。
>>492 > この場合にはtypename の次には少なくとも一つネームスペースとしてのクラス名
> が必要なのです、と文法できまっています。よって
> typename A<T>::value_type t または
> typename B::value_type
> とかけばよいです(
>>491は通るよね?)。
なるほど、勉強になりますた。
>>491は通ります。
void f( typename B::value_type a ){}
でいくことにします。
> 後者だとstd::iteratorの存在意義があまりない罠。
まったくですね。なんか納得がいかない。むかつく。
ムカツク!禿ムカツク!禿バカジャネーノ!?と言いながらキーボードに
こぶしを振り下ろすとよいです。安物のキーボードのほうが殴ったときに
たわんだ感じがしてより自己効力感を得られるし、万が一壊したときの
損害も少なくてすむので、ベターです。
>>502 いや
>>492の意見を取り入れるとBCCの方はわかりませんが
VC++の方は部分特殊化がないからでは。
>>501 ノートパソコンなので、無理です。
>>492 >
>>485 > Aが特殊化されていたら A<T>::value_type が存在しない/型名でない可能性
> があるのです。
コンパイラにはそういうときだけ
(A<T>が特殊化されてvalue_typeが存在しない typename T に対して
B<T>が実体化されたときだけ)
エラーを出してほしいと思うのですが、それは標準ではない、
ということなのでしょうか。
>>502 footypeでもfoo<T>::footypeでも特殊化を考慮するとこれが型名であるとは
(Tが未決定の時点では)決定できないのでtypenameつける以外は違反
になってしまう?まぁ実装では
>>504の望むようになっているけど。
標準じゃないから認めんとか言い出したら、禿ムカツクってことで泣き寝入りを。
>>503 VC6でも↓は通らないから、このケースでのvcとgccの違いは警告を出すか
どうかだけなんではないかな。bccは入れてないからわからない。
template<typename T>
struct A
{ typedef T value_type; };
template<>
struct A<char> /* 特殊化(value_type未定義)*/
{};
template<typename T>
struct L: public A<T>
{ void f(A<T>::value_type t){} };
int main() {
L<int> li;
L<char> lc;
li.f(0);
lc.f('0');
}
>>505 >このケースでのvcとgccの違いは警告を出すかどうかだけなんではないかな
確かにそうかもね。その点では案外VC++が優秀なのかもね。
g++ -wじゃ全部の警告消えちゃうしね。
それから、この特殊化の例が通ると怖いね。
"VC++"は6と7と7.1で激しく標準準拠レベルが違うので
バージョン明記してくれ~
暴力的だな(笑)
おれのキーボードは昔ながらの四角いやつなんだけど
キータッチが別れてるやつって使いやすいの?
買おうかどうか迷ってるんだよ。
STLつかうと一気に実行ファイルサイズが10倍に?!
なるね。たまに。
最近はサイズなんて気にしてないな
>>511 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
すごいよこの人(以下自粛)
スマソ。
>511
向こうのスレのループを持ち込むな
もまえら、釣られてはいけません
僕の名前はエンポリオです。
518 :
デフォルトの名無しさん:03/07/13 23:22
糞スレ化の危機により緊急age
質問カモ~ン
>518
ageルナ。
>>492 Aが特殊化されていたら A<T>::value_type が存在しないというのは
具体的にはどういうときに起こるのでしょうか?
特殊化が分かってなかったみたいだ。出直してきます。
523 :
デフォルトの名無しさん:03/07/14 13:51
どかーん
524 :
デフォルトの名無しさん:03/07/14 17:32
STLのvectorって、小さくresizeしてもメモリ開放してくれない、って本当ですか?
そうなら、小さくなった場合vector再作成しなきゃならないですか?
ってそんな処理書くの手間なような。
525 :
デフォルトの名無しさん:03/07/14 18:27
この場合の、Aってなんていう名前なんでしょうか?
名前がわからないので、ググることもできないんで、、、
ご存知の方、教えてください。
class A;
class B {
int c;
A *m_a;
};
前方宣言
526が当たってたら、俺カッコよすぎるな・・・
>>525 名前も何もAて言うクラスじゃん。
しかも、それは宣言のみだからどこかに定義がなけりゃ使えん。
前送り宣言て訳してる本もあったな。
ぐ~ぐるではヒットしなかったが。
531 :
デフォルトの名無しさん:03/07/14 18:59
>>527 クラスAの宣言文をなんというかが知りたいんです。
以前、「抽象クラス」っていう、って文を見たことがあるんですが、
ぜんぜん自信がありません(し、ググってもそれらしいのは見つからない)
でも、Javaの抽象クラスとは意味が違って紛らわしいなぁと思った
記憶はあるんですが。
532 :
デフォルトの名無しさん:03/07/14 19:02
forward declaration
534 :
デフォルトの名無しさん:03/07/14 19:05
>>533 ありがとうございます。
前方宣言でいいようです。ぐぐったらヒットしまくりました。
ありがとうございました。
でも正規表現とかだとそっちは後方だよね。
後方宣言で通じる奴はいないだろうけど。
>>535 正規表現だと"後方参照"だから、宣言があるのは前方、
参照があるのは後方、でいいのではないかなあ。
>>539 現在位置より先を読むんだから普通に"先読み"表明で何か問題あるか?
後読み表明って聞いたこと無いからわからんが。
>>540 後読み表明ってひそかにマイナーだったんだな
「後読み」や「後読みアサーション」でググってくれるとヒットする。
スレ違いな話題はここまで。
>>495 「::」で修飾されないシンボルの検索では,
テンプレート引数に依存する親クラスは考慮されない。
だから、
template <class T>
struct Iter : public iterator<input_iterator_tag, T> {
void foo(value_type) {}
};
はダメだが、
struct Iter2 : public iterator<std::input_iterator_tag, int> {
void foo(value_type) {}
};
は問題ない。
以前ハマって仕様書調べたことがある。
g++ 3.3 だと御丁寧にも
implicit typename is deprecated,
please see the documentation for details
と言われる。
>>524 禿しくガイシュツ杉。
swap技法で検索するがよろし。
544 :
デフォルトの名無しさん:03/07/14 23:38
>>543 > 「::」で修飾されないシンボルの検索では,
> テンプレート引数に依存する親クラスは考慮されない。
...中略...
> 以前ハマって仕様書調べたことがある。
それはつまり
>>502ということですか?
deprecatedってことは昔はokだったのね
__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
547 :
低LVで申し訳無い:03/07/15 11:34
二つの集合について要素が一対一の場合に
どちらからも相手を特定したいのですが
map<A, B> m_mapA2B;
map<B, A> m_mapB2A;
の二つを持たせてfindするしかないですか?
__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
飲斡磯稲飲斡
ほしゅ
553 :
デフォルトの名無しさん:03/07/19 09:54
gccのtemplateを、gcc下位versionにソース互換性
を持たせる様に巧く書けません。
下のコードですけど、
gcc version3.2.2では通りますが、
gcc version2.9.6では C<T>::C()のiteratorについて、
C<T>がmap templateを持ってないと怒られます。
typenameを消すとgcc version2.9.6で通りますが、
今度はversion3.2.2で通りません。
何がおかしいんでしょうか?
--------------------------------
template<class T>
class C {
public:
typedef map<T,T> TCont;
C();
};
template<class T> C<T>::C() {
typename C<T>::TCont::iterator iter;
}
---------------------------------
>>553 たんによけいです。gcc version 2.95.3-10で確認。
template<class T> C<T>::C() {
typename TCont::iterator iter;
}
>>553 GCC-2.9XはC++のテンプレートに関して期待したらダメだと思うけど。
テンプレート使う以上はGCC3以上必須。
>>554 ホンとですね...逝ってきます。
>>555 > GCC-2.9XはC++のテンプレートに関して期待したらダメだと思うけど。
うちの環境RedHat7.3がベースなので、
ほとんどがgcc-2.9.xです
(つд`)∴°
templateはそんなに悪くはないと思うが。それよりiostreamが・・・
boostとかlokiとかを愛する人達にはあの程度では物足りないのでつ。<template
stl程度止まりの人達には必要充分。
2.9.xって部分テンプレート特殊化できますか?
StlOnlyでも特殊化は使うと思うけど。
560 :
デフォルトの名無しさん:03/07/21 00:48
なんなんだ
578 :
デフォルトの名無しさん:03/07/21 13:27
[w]stringstreamが遅いんだが、もっと速くならんのかな。
580 :
578(1):03/07/21 14:27
#include<boost/lexical_cast.hpp>
#include<boost/timer.hpp>
#include<boost/smart_ptr.hpp>
#include<sstream>
#include<vector>
#include<string>
#include<iostream>
#define MAX_LOOP (100000)
#define B_PRE { boost::timer tmr;
#define B_START(i) for(int i=0;i<MAX_LOOP;i++){
#define B_END } std::cout << tmr.elapsed() << std::endl; }
#define B_FINALLY_BEGIN }
#define B_TIMER std::cout << tmr.elapsed() << std::endl;
#define B_FINALLY_END }
wchar_t* stringconcat_i(const wchar_t* s1,int ii2){
const int i1 = wcslen(s1);
const int i2 = 6*sizeof(int);
const int i = i1+i2+1;
if( i1 > i || i2 > i || i1< 0 || i2 < 0 || i < 0){
throw "stringconcat error";
}
wchar_t* w = new wchar_t[i];
if(!w){throw "error";}
wcsncpy(w,s1,i1);
#ifdef _MSC_VER
_itow(ii2,w+i1,10);
#else
swprintf(w+i1,L"%d",ii2);
#endif
return w;
}
581 :
デフォルトの名無しさん:03/07/21 14:40
int main(){//環境はVC2003 -O2(最適化) です
//(1)lexical_cast + wstring::operator+ + vector 0.343 0.359 0.343
B_PRE
std::vector<std::wstring> ar; ar.reserve(MAX_LOOP+10);
B_START(i)
ar.push_back(L"boost" + boost::lexical_cast<std::wstring>(i) );
B_END
//(2)試しに狡をする wstringstream + vector 0.25 0.234 0.234
B_PRE
std::vector<std::wstring> ar; ar.reserve(MAX_LOOP+10);
std::wstringstream s; s << L"boost";
B_START(i)
s.rdbuf()->pubseekpos(5);
s << i;
ar.push_back(s.str());
B_END
//(3) stringconcat + shared_ptr + vector 0.109 0.11 0.11
B_PRE
std::vector<boost::shared_ptr<wchar_t> > ar; ar.reserve(MAX_LOOP+10);
B_START(i)
ar.push_back(boost::shared_ptr<wchar_t>( stringconcat_i(L"boost",i) ));
B_END
//(4) stringconcat + vector 0.078 0.063 0.063
B_PRE
std::vector<wchar_t*> ar; ar.reserve(MAX_LOOP+10);
B_START(i)
ar.push_back( stringconcat_i(L"boost",i) );
B_FINALLY_BEGIN
B_TIMER
for(std::vector<wchar_t*>::iterator itr = ar.begin();itr!=ar.end();itr++){ delete (*itr); }
B_FINALLY_END
}
vectorの中身がいろいろちがうじゃねぇか。
結果を統一しないと、道具が遅い根拠にはならないだろ。
あと、
不要なマクロ使いすぎ。
deleteとdelete[]を混同してる。
newで0が返ってくるのは非標準。
>deleteとdelete[]を混同してる。
そうだったね。
for(std::vector<wchar_t*>::iterator itr = ar.begin();itr!=ar.end();itr++){ delete [] (*itr); }
に修正してください。
>vectorの中身がいろいろちがうじゃねぇか。
std::wcout << ar[i].c_str();でみたけどOKだったけどちがた?
>newで0が返ってくるのは非標準。
どのように処理するのがいいのでしょうか?
チッ
try {
Cls c = new Cls;
catch (std::bad_alloc& ex) {
// 確保できんかった
}
または、
Cls s = new(std::nothrow) Cls;
if (s == 0) {
// 確保できんかった
}
コンパイラ毎の対応は知らん。
>>585 - catch (std::bad_alloc& ex) {
+ } catch (std::bad_alloc& ex) {
同様にshared_ptrでなく、shared_arrayが正しいですね。
std::vector<boost::shared_array<wchar_t> > ar; ar.reserve(MAX_LOOP+10);
ar.push_back(boost::shared_array<wchar_t>( stringconcat_i(L"boost",i) ));
これも少し訂正してみました。
>>585 wchar_t* stringconcat_i(const wchar_t* s1,int ii2){
const int i1 = wcslen(s1);const int i2 = 6*sizeof(int);
const int i = i1+i2+1;
if( i1 > i || i2 > i || i1< 0 || i2 < 0 || i < 0){throw "stringconcat error";}
wchar_t *w= 0;
#ifndef BOOST_NO_EXCEPTIONS
try{w = new wchar_t[i];}
catch(...){
//delete [] w; //?
throw;
}
#else
w = new wchar_t[i];
if(w == 0){
//delete [] w;//?
throw std::bad_alloc();
}
#endif
wcsncpy(w,s1,i1);
#ifdef _MSC_VER
_itow(ii2,w+i1,10);
#else
int iResult = swprintf(w+i1,L"%d",ii2);
if(iResult == -1){throw"stringconcat error";}
#endif
return w;
}
結果を統一しろっつうのは、std::vector<std::wstring> で統一しろってことだよ。
まずは文字列の保持の仕方を固定にしろ。
あと、
BOOST_NO_EXCEPTIONSはユーザーが使うものじゃない。
速度のテストに条件コンパイル使ってたら結果がどれによるものかはっきりしない。
>>585 nothrow使ってもクラスのコンストラクタからの例外は飛んでくるぞ。
> BOOST_NO_EXCEPTIONSはユーザーが使うものじゃない。
ごめん。これはうそだった。ちゃんとドキュメントに載ってるな。
でも使い方が間違ってる。
このマクロが定義されているときは、コンパイラは例外処理をサポートしない。
590 :
578(その1):03/07/22 00:06
ごたごたしたので最後に整理しておきます。
>>588さん、ご指摘ありがとうございます。
//includeは580のを使ってください
#define MAX_LOOP (100000)
#define B_LOOP (3)
#define B_TYPE1 //片方の方が精度が良い
#define B_TYPE2 //片方の方が精度が良い
#define B_INI boost::timer tmr;double td1=0;double td2=0;
#define B_PRE td1=0;td2=0; for(int j=0;j<B_LOOP;j++){ { tmr.restart();
#define B_START(i) for(int i=0;i<MAX_LOOP;i++){
#ifdef B_TYPE1
#define B_TIMER1 td1 += tmr.elapsed();
#else
#define B_TIMER1
#endif
#ifdef B_TYPE2
#define B_TIMER2 td2 += tmr.elapsed();
#else
#define B_TIMER2
#endif
#define B_FINALLY_BEGIN }
#define B_FINALLY_END } B_TIMER2 } std::wcout << td1/B_LOOP << " : " << td2/B_LOOP <<std::endl;
#define B_TIMER B_TIMER1
#define B_END B_FINALLY_BEGIN B_TIMER B_FINALLY_END
591 :
578(その2):03/07/22 00:10
wchar_t* stringconcat_i(const wchar_t* s1,int ii2){
const int i1 = wcslen(s1);
const int i2 = 3*sizeof(int)+2;//3>(8*LOG10(2))
const int i = i1+i2+1;
if( i1 > i || i2 > i || i1< 0 || i2 < 0 || i < 0){ throw "stringconcat error"; }
wchar_t *w = new wchar_t[i];//std::bad_alloc() or SPEC
if(w == 0){throw"stringconcat error";}//(非標準)
wcsncpy(w,s1,i1);//no error
#ifdef _MSC_VER //VC
_itow(ii2,w+i1,10);//no error
#else //Other Compiler
int iResult = swprintf(w+i1,L"%d",ii2);
if(iResult == -1){throw"stringconcat error"; }
#endif
return w;
}
int main(){//環境はVC2003 -O2(最適化) です
B_INI
std::cout << "ループ終了時: スコープ脱出時" << std::endl;
//(1)lexical_cast + wstring::operator+ + vector
std::cout << "lexical_cast<wstring> , wstring::operator+ , vector<wstring>" << std::endl;
B_PRE
std::vector<std::wstring> ar; ar.reserve(MAX_LOOP+10);
B_START(i)
std::wstring s=L"boost"; s+=boost::lexical_cast<std::wstring>(i);
ar.push_back(s);
B_END
えぃ
593 :
デフォルトの名無しさん:03/07/22 00:15
VC++6.0を使っているのですが、
#include <iostream>
#include <map>
using namespace std;
int main()
{
map<int,int> mt1, mt2;
int a=10;
a;
return 0;
}
というプログラムを組むと、
warning C4786: 'std::reverse_bidirectional_iterator<std::_Tree<int,std::pair<int const ,int>,std::map<int,int,std::less<int>,std::allocator<int> >::_Kfn,std::less<int>,st
d::allocator<int> >::iterator,std::pair<int const ,int>,std::pair<int const ,int> &,std::pair<int const ,int> *,int>' : 識別子が '255' 文字に切り捨てられました (debug 情報内)。
などの警告が6つでます。
また、最初のintをstringに変えると(#include <string>済み)、77個の警告が出ます。
どうすればこの警告は消えるのでしょうか?
594 :
578(その3):03/07/22 00:18
//(2) wstringstream + pubseekpos + vector
std::cout << "wstringstream , vector<wstring>" << std::endl;
B_PRE
std::vector<std::wstring> ar; ar.reserve(MAX_LOOP+10);
std::wstringstream s; s << L"boost";
B_START(i)
s.rdbuf()->pubseekpos(5); s << i;ar.push_back(s.str());
B_END
//(5) stringconcat + wstring + vector
std::cout << "stringconcat , vector<wstring>" << std::endl;
B_PRE
std::vector< std::wstring > ar; ar.reserve(MAX_LOOP+10);
B_START(i)
wchar_t *wA = stringconcat_i(L"boost",i);ar.push_back(std::wstring(wA));delete [] wA;
B_END
//(3) stringconcat + shared_ptr + vector
std::cout << "stringconcat , vector<shared_array<wchar_t> >" << std::endl;
B_PRE
std::vector<boost::shared_array<wchar_t> > ar; ar.reserve(MAX_LOOP+10);
B_START(i)
ar.push_back(boost::shared_array<wchar_t>( stringconcat_i(L"boost",i) ));
B_END
//(4) stringconcat + vector
std::cout << "stringconcat , vector<wchar_t*>" << std::endl;
B_PRE
std::vector<wchar_t*> ar; ar.reserve(MAX_LOOP+10);
B_START(i)
ar.push_back( stringconcat_i(L"boost",i) );
B_FINALLY_BEGIN
B_TIMER
for(std::vector<wchar_t*>::iterator itr = ar.begin();itr!=ar.end();itr++){ delete [] (*itr); }
B_FINALLY_END }
きゃはは
>>578 何を整理したつもりなんだ?混沌としたままじゃないか?
それじゃテストにならん。
引き取るか出直すかしてきてくれ。
599 :
デフォルトの名無しさん:03/07/22 11:34
>>597 一言一言、う○ーな。
テストなんかしてねーよ。
578-579をよく読め。
600 :
デフォルトの名無しさん:03/07/22 20:14
#include <windows.h>
#include <map>
class Draw {
private:
static map< HBITMAP, int > hBit;
static map< HDC, int > memDC;
public:
InitDraw();
};
error C2143: 構文エラー : ';' が '<' の前に必要です。
error C2059: 構文エラー : '<'
error C2238: ';' の前に不正なトークンがあります。
おそらくHBITMAPなどのせいかと思いますが、どのようにすればよいのでしょうか?
using namespace std;
付け足したらうまくいきました・・・
602 :
デフォルトの名無しさん:03/07/22 20:27
あれだあれがねぇ。
STLを使う前のあの呪文がねぇ。
std::map
これって常識?
template<typename TYPE, size_t N>
inline size_t elemof(TYPE (&)[N]) { return N; }
うーん。やっぱ常識だったか。
追加情報もありがトン。
609 :
デフォルトの名無しさん:03/07/25 04:33
マクロなのに名前空間内に入ってるように見せかけてみるテスト。
namespace Count
{
template<typename T, size_t N>
inline const char (&elemof_(T (&)[N]))[N];
const int elemof_unity_ = 1;
}
#define elemof(array) elemof_unity_ * (sizeof Count::elemof_((array)))
しまった。elemof_unity_ の型は size_t だ。
>>609 それじゃ elemof_unity_ の意味がないだろ。
const size_t elemof_unity_ = sizeof(char);
#define elemof(array) ((sizeof Count::elemof_((array))) / elemof_unity_)
こうじゃないのか?
あと、template 引数の size_t はこの場合、int のほうがよかないか?
>>613 それじゃ、Count::elemof( a ) と書けないだろ。
>>615 elemof_unity_ の意味を勘違いしてたよ、スマソ。
別の名前空間で elemof を定義できないから
これじゃ意味が無かったなー。
と今さら言ってみる。
618 :
デフォルトの名無しさん:03/07/28 19:54
STLにメモリストリーム系ありますか?
printfを書き換えるのに使えるようなものが欲しい。
printfを書き換えるってメモリ上の関数を書き換えたいのか?
iostream も boost::format も STL じゃないね。
てかSTLって何よ。
C++の標準ライブラリなんてほとんどテンプレートじゃないかと
思うんだが。
iostreamってテンプレートだったんだ。へー。
>>623 iostream は、basic_iostream テンプレートクラス の typedef だろ?
625 :
デフォルトの名無しさん:03/07/29 14:51
typedef basic_iostream<char, char_traits<char> > iostream;
stringってテンプレートだったんだ。へー。
typedef basic_string<char, char_traits<char> > string;
ちょっと違った。
typedef basic_string<char, char_traits<char>, allocator<char> > string;
たまには釣られてみるか
>>627 typedef basic_string<char, char_traits<char>, allocator<char> > string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<char> > wstring;
pair<T,U>のコンテナを pair の second に従ってソートさせたいのですが、
関数アダプタとかをうまく組み合わせて共通アルゴリズムの sort でソートできませんかね?
compose 系と select2nd でいける。
>>632 compose も select2nd もVC6にはないや・・・
stlportとかboost入れたら?
stlportを入れておくべきかと、
環境が固定されてるとかで入れられないなら、作ってもよし。こんな感じで。
template< typename FN, typename OP1, typename OP2 >
struct binary_compose:public std::binary_function<OP1::argument_type, OP2::argument_type, FN::result_type>
{
FN& fn;
OP1& op1;
OP2& op2;
binary_compose(const FN& f, const OP1& p1, const OP2& p2):fn(f), op1(p1), op2(p2) {}
result_type operator( first_argument_type p1, second_argument_type p2){
return fn( op1(p1), op2(p2) );
}
}
template< typename FN, typename OP1, typename OP2 >
binary_compose< FN, OP1, OP2 >
compose2(const FN& f, const OP1& p1, const OP2& p2)
{
return binary_compose<FN, OP1, OP2 >( f, p1, p2 );
}
template<class PAIR>
struct select2nd : std::unary_function<PAIR,PAIR::second_type> {
PAIR::second_type operator()(const PAIR& x) const
{
return x.second;
}
};
636 :
デフォルトの名無しさん:03/07/29 22:04
以下のコードがVC7では通っていたのに準拠度が上がったらしいVC7.1では
warningとerrorが出て通らなくなってしまったんですが
何がマズイんでしょうか?
template<typename T> class Manager
{
protected:
typedef std::list<T*> Array;
typedef Array::iterator ArrayIterator; //ここでwarningとerror
Array Items_;
public:
virtual ~Manager() { Clear(); }
void Add(T* item) { Items_.push_back(item); }
void Add(const Array& array){ Items_.merge(array); }
int size() const { return Items_.size(); }
void Clear()
{
for(ArrayIterator it=Items_.begin(); it!=Items_.end(); ++it)
delete *it;
Items_.clear();
}
};
エラーとワーニングはこんな感じです
warning C4346: 'std::list<_Ty*>::iterator' : 依存名は型ではありません。
型を指定するには、'typename' を含むプレフィックスを使用してください。
コンパイルされたクラスのテンプレートのインスタンス化 'Manager<T>' の参照を確認してください
error C2146: 構文エラー : ';' が、識別子 'ArrayIterator' の前に必要です。
error C2501: 'Manager<T>::ArrayIterator' : 識別名を宣言するのに、型が指定されていません。
638 :
デフォルトの名無しさん:03/07/30 00:36
>631
Uの比較をする関数をつくって、sortに渡してやればいいです。
>>636 >typedef Array::iterator ArrayIterator;
ここは
typedef typename Array::iterator ArrayIterator;
こう
Array::iteratorだけではそれが型名かどうか判別できないから。
640 :
デフォルトの名無しさん:03/07/30 15:11
string sbuf;
cout << sbuf;
みたいに書けないんでつか?
なぜそう思うのですか?
643 :
デフォルトの名無しさん:03/07/30 16:27
>638
違った。
sortに渡すのは、pairのsecondを比較する関数。
Uの比較演算子の定義もするという、二段構えだと、オブジェクト指向っぽいね。
>>640 おそらく
#include <string>
を忘れている。
646 :
デフォルトの名無しさん:03/07/31 00:51
>640
vc6だとできなかっった鴨試練。
代わりに
cout << sbuf.c_str();
とでもして。
>>646 できないのは VC5 までじゃなかったっけ?
うろ覚えだが。
実は#include <iostream.h>
実は
basic_ostream<char>&
operator<<(basic_ostream<char>&, const string&);
の定義がない罠
649は、きっとあまりかしこくないひとなんだろうなぁ、とおもいました。
えへへ。誉められちった。あまりだって。
実は
std::
を付け忘れてるとか
実は関数外
うしんぐ なめsぱせ std
struct A { string str; int i;}
typedef std::vector<A> B;
typedef std::vector<B> C;
class D {
std::vector<C> vec;
int flag
void vsort(int index);
};
の時、vsort内でstd::sortを使ってvec内のB[n].strをキーにしてvecをソートしたいの
ですが、どうすればいいですか?flag==indexの時は逆順ソートがしたいです。
叙述関数ってのが良くわかんないです。
>vec内のB[n].str
nはどっから出てきた?
すみません、B[index].strでした
(^^)
どのB[index].strを使って比較するの?
setに格納されている要素のアドレスを取得できないんですか?
vectorだと&vec[0]とかで、mapだと&m[7]見たいな感じでアドレスが取得できるみたいだけど
setの場合はどうしたらいいの?
set<int>::iterator it = s.find(7);
int* p =
だとイテレータのアドレスになってしまうよね。
変なことやってると思うかもしれないけど既存のCのプログラムとの関係でアドレスが欲しいです。
setじゃ無理かな?教えてください。
>>660 > vectorだと&vec[0]とかで、mapだと&m[7]見たいな感じでアドレスが取得できる
vector以外でそれやるの危険では・・・。
template <typename T1,typename T2=NullType,typename T3=NullType,typename T4=NullType>
struct GenTypelist;
template <typename T1>
struct GenTypelist<T1,NullType,NullType,NullType>{
typedef TYPELIST_1(T1) Result;
};
template <typename T1,typename T2>
struct GenTypelist<T1,T2,NullType,NullType>{
typedef TYPELIST_2(T1,T2) Result;
};
template <typename T1,typename T2,typename T3>
struct GenTypelist<T1,T2,T3,NullType>{
typedef TYPELIST_3(T1,T2,T3) Result;
};
typedef GenTypelist<char,short,long>::Result Intengers;
ふと思いついたんだけど、既出?
BOOST_PPのあたり使って作っておくと面白そう
template <typename T1,typename T2=NullType,typename T3=NullType,typename T4=NullType>
struct GenTypelist{
typedef Typelist<T1,GenTypelist<T2,T3,T4,NullType>::Result> Result;
};
template <>
struct GenTypelist<NullType,NullType,NullType,NullType>{
typedef NullType Result;
};
書き込んでから思いついた・・・
>>662 *((&m[0]) + i) とかはvector以外では無理だが、
別に単にアドレスとっても問題なかろう。
>>661 どうもありがとう。
初め見たとき参照のアドレス?みたいなのになってエラーになるかと思ったけどならないのね。
ただ返す型はconst int *になってたみたい。setは内容変えないようになってるんだね。
まあ自分のプログラムも変えないからconstへのポインタでOKなんだけど。
>>662 ほんのちょっとの間、Cの関数に渡すのです。
その間、要素を削除しないことは保証できるから大丈夫なんじゃない?
実際はintなんかじゃなくてもっと大きい構造体なんかが入ってるからポインタ渡しになってます。
std::setの場合、要素が変更されると整列が狂うから。
std::string::_Rep::_M_grab(std::allocator<char> const&, std::allocator<char> const&)
ってgdbに言われました。しかし、意味がわかりません・・・
ore % g++ --version
g++ (GCC) 3.2 20020927 (prerelease)
Copyright (C) 2002 Free Software Foundation, Inc.
冒頭のメッセージは一体何を伝えたいのでしょうか・・・。
stlportの
vectorとlistのソートの実験したら、listの方が3倍くらい早かった。
671 :
デフォルトの名無しさん:03/08/12 21:08
std::fstream の読み書きがうまく行かなくて困っています
stlport、vc6 です
ファイルを読みこんで、その中身を元に末端にデータを追加するんですが、
読み込みしかできないのです
std::fstream file;
file.open ( "test.txt", std::ios::binary | std::ios::in | std::ios::out );
.............// read など
.............// データ解析
.............// write など
file.close();
読み書きが出来る様にする方法を教えてください
おねがいします
app
>>670 boost::shared_ptr で実験してみました。
intのメンバだけもったクラスをポインタにしてみたんだが、
1000個くらいのポインタをコンテナにぶち込んだあと
intでソート、その後ポインタでソートを10000回くらい繰り返してみた。
まぁ、1000個ポインタぶち込むとこからループさせたらあまりかわらなくなったけどね。
>>671 www.scl.kyoto-u.ac.jp/scl/appli/appli_manual/SUNWspro/WS6U2/ja/manuals/stdlib/user_guide/loc_io/index.htm
homepage1.nifty.com/emil/stream.html
homepage1.nifty.com/tnomakuchi/studying/programming/iostream.htm
www.jah.ne.jp/~naoyuki/Writings/ExtIos.html
ahiru.portland.co.uk/tips/stlsmp.shtml
www5c.biglobe.ne.jp/~ecb/cpp/cpp00.html
www.kab-studio.biz/Programing/Codian/iostream/06.html
ifstream と ofstream の2つで代用しました
お騒がせしました
失礼致します
>>673 std::iter_swap<std::list<T>::iterator, std::list<T>::iterator>
がうまく特殊化されてるんじゃないの?
ifstream で2回オープンすると、ちゃんとファイルが読み込めないようなのですが
なぜでしょうか?
677 :
デフォルトの名無しさん:03/08/13 23:09
template関数やクラスに、型を適用したあとのソースを出力してくれるような
プログラムありませんかね?
>>677 ×template関数
○関数template
×template関数やクラス
×関数やクラスtemplate
std::stringで検索しても良いHP出ないのナンデダロ-
お気に入りに入れてるお勧めなHPありますか?
>>681 std::string のなにを知りたいんだ?
>>682 681の知りたいことを予想してみる。
ずばりcodecvt。
ていうかむしろ俺が知りたい。
日本語でよろしく。
ググレってか?
(⌒V⌒)
│ ^ ^ │<これからも僕を応援して下さいね(^^)。
⊂| |つ
(_)(_) 山崎パン
_,......,,,_
,、:'":::::::::::::::::``:...、
/::::::::::::::::::::::::::::::::::::::\
i::::::::::::::::::::::::::::::::::::::::::::::::::ヽ
!::::::::::::::::::::::;‐、:::::::::_::::::_::::';
|::::::::::::::::::::::| :: ̄ ``!
r''ヾ'::::::::::/ :: |
l r‐、\::/ _,,、ii_;;_、 _,,,l、
ヽヾ〈 ::= -r:;;j_;、`/ :;'ィ;7
!:!_,、 :: ` ー : |: `´/
,./ヽ | 、_ :: ,: 'r' :i |: /
,../ `ヽ;_ i | '"、_:::__`:'‐'. / なんかもう必死でしょ?
/ ``'ー 、_\ ! `::` ̄''`チ`シ
/ー 、_ `\:、_ :: ` ̄/ 最近の山崎渉
/ ``ヽ、 ヽ`'7‐--'゛
687 :
デフォルトの名無しさん:03/08/15 21:04
要素数を3に限定したvector<int>ってどうやってつくんの?
なんでint[3]じゃだめなんだろう
イテレータが使いたいとか
>>687 const vector<int> v(3);
意味なし
692 :
デフォルトの名無しさん:03/08/16 01:28
boost::array<int,3>はどうだ
695 :
デフォルトの名無しさん:03/08/16 02:25
>>693 さっそくboostを入れました。
typedef boost::array<int, 3> bai3;
で、できました。
std::vectorで同様のことができなそうなので、あきらめます。
ありがとうございました。
>>694 ((((((≧∇≦)))))) ブハハハハ
698 :
デフォルトの名無しさん:03/08/16 09:23
export の実装されてるコンパイラって、やっぱ未だにないの?
かなり前からcomeau C++がサポートしてるよ。
701 :
デフォルトの名無しさん:03/08/16 17:30
>>701 TYPELIST_2() とか TYPELIST_3() とかいう要素数が名前に入った
マクロ使わずに GenTypeList<>::Result で書けて便利、てことじゃねーの?
mpl 使えって感じだが。
704 :
デフォルトの名無しさん:03/08/16 18:37
XMLでシリアライズしてくれるライブラリってある?
>>700 おー。1つはあったんですね。
それ以外にはもうないんでしょうか?
>>703 まあそういうこと
要素数が増減する時に便利かな、と思う。
?んなのLokiに入ってるだろ?
前Lokiのソース見た時あったぞ
709 :
デフォルトの名無しさん:03/08/17 10:22
質問です。g++ (GCC) 3.2 20020927 (prerelease) で
template <typename T>
class CTypeAttribute
{
private: template <typename U> class CNonConst { public: typedef U ResultType; };
private: template <typename U> class CNonConst<const U> { public: typedef U ResultType; };
public: typedef CNonConst<T>::ResultType NonConstType;
};
としたら、public: typedef CNonConst<T>::ResultType NonConstType; の行で
ResultType は implicitly a typename だという警告が出てしまいます。
暗示的な型ってどういう意味でしょう?警告の抑制以外で、この警告を出さないようにするには?
よろしくお願いします
このスレの前の方みたら似た例が出てました。スミマセン。
public: typedef typename CNonConst<T>::ResultType NonConstType;
ですね。
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
☆★ 無修正DVD★☆なら 新宿歌舞伎町直送 ☆★
人気爆発新作ベスト9入荷
堤さやか引退特集 憂木瞳 プロジェクトX No8 ベイビーフェイスをやっちまえ
白石ひより・愛葉るび SNAPSHOT 地下映像陵辱援交 すぎはら美里痴女教師
店頭販売の売れ筋のみ厳選してみました 安心の後払い
http://book-i.net/moromoro/ 白石ひとみ 小森詩 山田まり 長瀬愛
@@ 及川奈央 レジェンド @@ 堤さやか 東京バーチャル 依然大好評
サンプル画像充実 見る価値あり 最高画質
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□
□□□■■□□□□□■□□□□□□□■■■■■■■■■■■■□□
□□■■□□□□□■■■■■■□□□□□□□□□□□□□■■□□
□■■□□■□□□■□□□□■□□□□□□□□□□□□■■□□□
□□■□■■□□■■■□□■■□□□□□□□□□□□■■□□□□
□□□■■□□■■□■■■■□□□□□□□□□□□■■□□□□□
□□■■□□□□□□□■■□□□□□□□□□□□■■□□□□□□
□□■□□□■□□□■■■■□□□□□□□□□□■□□□□□□□
□■■■■■■□□■■□□■■□□□□□□□□□■□□□□□□□
□□□□■□□□■■□□□□■■□□□□□□□□■□□□□□□□
□□■□■□■□□□□■■□□□□□□□□□□□■□□□□□□□
□□■□■□■□□□□□■■□□□□□□□□□□■□□□□□□□
□■■□■□■□□□□□□□□□□□□□□□□□■□□□□□□□
□■□□■□□□□■■■□□□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□■■■□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□□□■■□□□□□□■■■■□□□□□□□
714 :
◆bYHudLsQLw :03/08/20 07:10
Effective STLを読んでいるのですが、
関数オブジェクト・ファンクタ・ファンクタクラスが良く分かりません。
豊富に例が載っているサイト・書籍を紹介していただけませんか?
関数オブジェクトとファンクタの違いがわからん
C++第3版では関数オブジェクト、
Effective~ではファンクタと呼んでるが
同じものかな?
>>716 C++第3版のP593に、
関数呼び出し演算子を持つクラスのオブジェクトは、
関数的オブジェクト: function-like object, functor あるいは単純に
関数オブジェクト: function object と呼ばれる。
って書いてある。つまりまったく同じ物を指してる。
おお分かった。つまり
関数オブジェクトはその名の通り関数の機能を持つオブジェクトで
内部状態を持ち得ない。ファンクターは関数的なオブジェクト、
すなわち形式的に関数オブジェクトと同じ形をしているもので
内部状態を持ち得る、或いは持っている物を指す。といった具合か。
ん?つまり違う物を指すんじゃないか
>つまりまったく同じ物を指してる。
この結論はどこから?
スゲー馬鹿だな
>>719 (゚Д゚)ハァ?(゚Д゚)ハァ?(゚Д゚)ハァ?(゚Д゚)ハァ?(゚Д゚)ハァ?(゚Д゚)ハァ?
なんだ文句あるのか。受けて立つぞ
話が低次元過ぎてあなたと喧嘩なんかするつもりになれません。
基礎からC++をやり直される事をおすすめします。
しっぽ巻いて逃げたか
負け惜しみなんか言ってる暇があったらもっとC++を勉強しろ。
俺は達人だからな勉強する必要などない。お前らはもっと勉強しろ。
関数と内部状態の関係が分からなかった奴は特にな
何を持って達人と自称してるか知らないが、性格が悪そうだから
どっちみち先が見えてるな。
>何を持って
漢字が違うよバーカ
重箱の隅をつつく所なんかいかにも嫌らしいねえ。
そのくせ日本語が不自由
ま、こんな奴には絶対友達いないな。
733 :
デフォルトの名無しさん:03/08/20 22:31
さらしあげ
釣られるなよ...。
736 :
デフォルトの名無しさん:03/08/21 01:40
取り込み中、アホな質問で申し訳ないのですが…
メンバとしてもっているstringやlistは
そのオブジェクトをdeleteするときに、list::clear()や
string::remove()しなければいけないのでしょうか?
>>736 list や string のデストラクタでちゃんとやってくれる。
>>737 レスありがとうございます!
が、すいません、ということはやっぱり
明示的にlistなどのデストラクタを呼ばなきゃなのでしょうか?
勝手にやってくれるのかな…でもスコープ
外れるわけでも、delete使うわけでもないし…うーん
>>738 Java厨?それともC#厨?
C++ だと、new で動的に確保したのは delete しないと駄目だけど、
静的確保した変数はデストラクタ自動的に呼ばれるよ。
レスが遅れてすいません。
お答えいただいた方どうもありがとうございました。
質問させてください。
template<class T=int>
class A
{
public:
T param;
A(const T& x=0){param = x;};
~A(){};
};
int main()
{
int i=0;
A<int> c1(1);
A c2(1); //エラー
A<int> c3(i);
A c4(i); //エラー
return 0;
}
毎回型を指定するのは面倒だと思ったんで、上みたいにテンプレートクラスに
デフォルトの仮引数リストをつけたんですが、なぜか、明示的に宣言して
いない場合には宣言しろとコンパイラに怒られます。
でもSTLのvectorを使うときとかはallocatorを指定しないですむからデフォルトの
仮引数リストをつけること自体は間違ってはずなんです。ってことはやっぱり上の
ソースのどこかが間違ってると思うのですが、分かりません。誰か上のどこがまずいか
教えてください。よろしくお願いします。
>>742 <>は省略できない。
template <class T = int>
class A
{
public:
T param;
A(const T& x = 0) {param = x;};
~A(){};
};
int main()
{
int i = 0;
A<int> c1(1);
A<> c2(1); //エラー
A<int> c3(i);
A<> c4(i); //エラー
}
>>743 即レスサンクス
なるほど、テンプレートの機能を利用しているということを
コンパイラに明示的に伝えないといけないから"<>"だけは
省略できないわけか。
ありがとうございます。勉強になりました。
よく使う型のやつは typedef してもいいかもね。
746 :
デフォルトの名無しさん:03/08/29 00:10
>>97 VC7.1以外はやめといたほうがよさそうよ
寝ぼけて化石レスしちまった。すまん。
しかもageてるし俺...頸吊って着ます
BorlandはC#なんか作らんでC++のコンパイラを早く完璧にしろ。
Comeau C++
ComeauはBoost100%じゃないじゃん。
VC++7.1の方がいい。
しかし、Boost は C++ 準拠率のモノサシみたいだな...。
大手を振って使えるようになる日は近いとは思うけど、
何か複雑な気分だな。
>>752 boostは C++ Standards Committee Library Working Group の連中が
始めたプロジェクトなわけだし
boost を作れば、
開発速度が boost されるだけじゃなく、
C++ 準拠率も boost するってか?
boost を作れば???
boostってそれぞれのコンパイラに合わせて修正してるから
C++のモノサシにはなれないよね。
だから、テンプレートを正しくコンパイルできるものが一番、C++らしいんじゃないの。
そのてん、VC7.1っテンプレートの挙動直ったの?
直った。lokiも通る。
おおぉ!おれっちのVC7だから買い替えないとあかんなー。
WTLって今どうなってるの?
.NETに喰われた
ATLって今どうなってるの?
.NETに喰われた
STLって今どうなってるの?
いや、加速中だろ。
おあとがよろしいようで。
>>761 例によって首位を独走中。
>>763 1ゲーム差だけど一応首位にいるよ。
プホルスには頑張って欲しいね。
あ~仕事でもVC7.1つかいて~
でwtlはどうなったのかと
.NETに喰われた
でも消化不良を起こしているぽい
どこかでWTL 7.1なんて話を聞いたことあったんだけどなぁ。
頼むから出てくれ。
773 :
デフォルトの名無しさん:03/09/09 21:38
std::stringをリターンする関数作ってもメモリリークないですよね?
>773
ないよ。
775 :
デフォルトの名無しさん:03/09/09 21:43
>>775 返り値をどこかに代入した後すぐにstd::~string()のデストラクタが呼ばれる
だろう。一時変数だからね。
>>775 それ以前に、なぜリークすると思うのか謎なんだが……。
779 :
デフォルトの名無しさん:03/09/09 22:18
クラスXにオーバーロードされたメンバ関数fooがあるとき、その関数を
boost::bindの第一引数に指定しようとすると
bind(static_cast<void(C::*)(int,int)>(&C::foo), ...);
などと冗長な書き方をしなければならないような気がするのですが、
もっとスマートな書き方があったら教えて下さい
>>773 リークはなくてもパフォーマンスが悪いと思うのだが
781 :
デフォルトの名無しさん:03/09/09 22:19
>780
参照で返せとでも?(わら
>>781 一時変数の参照をか?参照した途端にあぼ~んだな(w
783 :
デフォルトの名無しさん:03/09/09 22:22
ATLの質問もOK?
>783
だめ
>>780 std::string はふつーリファレンスカウント & copy-on-write で
実装してあるから、それほど悲惨な結果にはならんよ。std::vector<char>
使うよりは大分マシ。
787 :
デフォルトの名無しさん:03/09/09 22:25
>>789 コードチューニングは、まずプロファイルとってからな。
落ち着けよおめーら
パラメータで参照渡すなら戻り値なぞいらんわ
>>792 いらない、が、コピー走らせて戻り値返すよかマシでない?
お前らCOWだと何回言ったら。
結論としては780はビギナー。
>>779この方がいくらか良くないですか?boost::bind<void, int, int>(&C::foo, ...)
STLのリファレンスとして使えるお勧めの書籍はありますか?
EffectiveSTLを一通り読んだのですが、例が少なくて・・・
できれば、boost等も扱っていると助かるのですが
どなたか、よろしくお願いします。
>>802 STLは
C++標準ライブラリ、チュートリアル&リファレンス ISBN 4-7561-3715-6
Boostは
SourceForgeに行ってBoost日本語化プロジェクトのzipをDL。1.29のだけど
結構使える。関係ないけどこのプロジェクトは俺も参加している。最近全く
訳してないけど。
804 :
デフォルトの名無しさん:03/09/10 18:02
なんでfunction_traitsってないの?
ごめん。boostにあった。
>>789 void foo(string& s);
string s;
foo(s);
よりは、
stirng foo();
string s = foo();
のほうが効率いいと思う、たぶん。
あの、初歩的なことかもしれませんが、教えてください。
bjamでBoostライブラリをコンパイルしました。
で、ライブラリとして使うのは、*.libファイルだけですよね?
*.objはいりませんよね?
プログラミング以前の問題ですが、お願いします。
修正
>で、ライブラリとして使うのは、*.libファイルだけですよね?
で、ライブラリとして使うのは、*.libファイルと*.dllファイルだけですよね?
template<class A, class B>
void f(pair<A,B> &p);
とかいう関数を使う場合に、
pair<int, int> p;
f(p);
とするとコンパイルエラーになります。どうしてですか?
>>811 class を typename に変更してみては?
>>811 #include <utility>
using std::pair
815 :
デフォルトの名無しさん:03/09/11 17:59
boost::spirit詳しい人いませんか?semantic actionまわり。
iniファイルのパーサのようなものを作成しているんですが、
line = (name >> '=' >> value[ _action1_ ])[ _action2_ ];
となっているとき、
_action1_ で、nameの値(文字列)を参照するか、
_action2_ で、name,valueの値を参照するか、
そのどちらかを行いたいのですが...。可能でしょうか。
>>808 もちろん、foo() の中味によるんだけど、たとえば、
void foo(string& s)
{
const char* p;
//…
s = p; // (B)
}
string s; // (A)
foo(s);
だと、(A)のところでコンストラクタが走り、(B)のところで代入が起こるが、
string foo()
{
const char* p;
//…
return p; // (C)
}
string s = foo();
だと、(C) のところで直接sに対するコンストラクタが走るので。
>>818 それって、foo()の使用方法によるね。
例えばループ内でfoo()を呼び出すならvoid foo(string& s)の方が良いし、
単発かそれに相当する感じでfoo()を呼び出すならstring foo()の方が良いって事だよね。
でも(C)で直接sに対するコンストラクタが走るというのは、コンパイラに依存しない?
820 :
デフォルトの名無しさん:03/09/12 02:07
<<817
ありがとうございます。
_name_で名前を覚えるときって、nameルールのクロージャか、上位の
クロージャか、grammarに関連づけたクロージャか、それくらいしか
ないですよね?
ほかに何かあったら教えて下さい。
>>818 常識的に考えて。
関数が値を返すときに
string foo();
これだと一旦一時バッファでstringのコンストラクタがはしって
そして、コピーコンストラクタが走る。このように考えない?
あなたのその考えは確かに最適化したらそのような挙動で処理されるかもしれないですれど
実際の動作は、>819でもおっしゃってるようにコンパイラに依存します。
>821
コンパイラ作成者にとって、>818が言ってるように動作させるのが「常識」だし、
そのような動作をさせてもいいと規格にある。
RVOだっけ?
>823 うん。
Return Value Optimization.
IS 12.8.15 を参照。
825 :
デフォルトの名無しさん:03/09/12 12:19
またspiritなんですけど、
line = longest_d[str_p("A")[ _act1_ ] | str_p("AA")[ _act2_ ]];
に"AA"を喰わせると、_act1_ までも実行されてしまうんですが、これ
どうにかならんものですかね。。
boost::spirit って何の事だと思っていたら、
1.30にはあるんだな。
ウチは1.29だ。
新しくインストールしようっと。
const string& s= foo();
てのは?sがconstになってしまうけれども。
>>827 基本的には
string s=foo();
と同じなんじゃないの?多分。
>>825 spiritって先読み型のparserじゃなくてバックトラック型の
parserなのでねぇ。どうにもならんと思う。grammar を手で
変形して LL(1) な形にしておくくらいか。バカっぽいけど。
830 :
デフォルトの名無しさん:03/09/13 11:28
バックトラック型って禿げしく遅そうだね
>>818 return std::string(xxx);
な形で済ませられるならいいけど
fooに求められる仕様次第では
自分の首を絞めかねない気がするのですが…
>>832 だからといって、わかりやすさを犠牲にしてまで foo(String&)を使う
メリットがないってこと。
たとえ、foo()が行う処理がどれほど複雑であっても、
String s;
foo(s);
に比べて、
String s = foo();
の形で損になることは事実上ない。
Stringじゃなくて、vector<BigObject>みたいな場合は別だけどな。
Stringじゃなくて std::stringだった。 (-_-)
>>832 例外を投げるまでもない軽度のエラー処理を返り値で処理できない、
というのは充分に損だと思うが。
・腐れインターフェース1(w
HRESULT ret;
string s = foo(&ret);
・その2
string s = foo();
if( s == "" ){...}
if( s == "#!error" ){...}
・その3
errorno=0;
string s = foo();
if( errorno == ERROR_HOGE){}
例外を投げるまでもない ってなんだ?
ところで
string s = foo();
より
string s( (foo()) );
の方が良いのでは?と思う漏れは、まだ未熟者なんでせうか。
RVOでぐぐれよ。
それ以前の問題だろ。
>>837 未熟者。
std::string s;
s = foo()
std::string s = foo();
これは解釈が全然違う。
operator =
>>840 837は初期化と代入を比べているのではなくて、
2つの初期化の形について比べていると思うぞ。
>>837 共にコピーコンストラクタが動くだけだから、見た目で決めたら?
上の方が他人から好かれるだろうけど
>>835 腐ってるねぇw、その2に至っては仕様的にも問題ありそう
>>843 RVOが適用されればコピーコンストラクタは呼ばれないけどね
おまえら、スレ違い。
テンプレートの話すれ。
846 :
デフォルトの名無しさん:03/09/14 15:44
/* mainの前に関数を実行するテンプレート */
template <void (*func)()>
class Constructor
{
Constructor(); /* 構築禁止 */
static struct Inner
{
Inner(){func();}
} instance;
};
template <void (*func)()>
typename Constructor<func>::Inner Constructor<func>::instance;
/* 使用法 */
void test(){std::cout << "test\n";}
template class Constructor<test>;
こんな感じで、ユーザーコード(どうせ自分しか使わないけど)に対して
明示的なインスタンス生成を要求するテンプレートを書いても良いのでしょうか?
>>846 書くのはお前の勝手だけど、コンパイルが通らんだろ。
>>847 vc7およびgcc2.95でコンパイル&動作確認しましたが。
>>848 MinGW(gcc3.3.1)でコンパイルが通らん。
Compiler: Default compiler
Executing g++.exe...
g++.exe "C:\MinGW\Learn\Learn3\before_main.cpp" -o
"C:\MinGW\Learn\Learn3\before_main.exe" -s -Wall -O2 -march=pentium4 -O3 -I"C:\mingw\include\c++" -I"C:\mingw\include\c++\mingw32" -I"C:\mingw\include\c++\backward" -I"C:\mingw\include" -L"C:\mingw\lib"
C:/MinGW/Learn/Learn3/before_main.cpp: In function `int main()':
C:/MinGW/Learn/Learn3/before_main.cpp:21: error: syntax error before `]' token
Execution terminated
スマソ}の変わりに]使ってた。わはははは
Σ(´Д`;) 漏れが使ってるBCCじゃコンパイルが通らねぇんだよぉ(鬱
(;´Д`)
>>846 よくわかんねーけどさ
bool test(){ /*...*/}
bool dotest=test();
main(){
}
これじゃだめなんか?
>>853 この場合はその通りです。
ただ、禿3版に
>言語は、明示的なインスタンス生成要求を必要としない。
>明示的なインスタンス生成は、最適化とコンパイル/リンク処理の
>手作業による制御のためのオプションのメカニズムである。
とあったので、積極的に使ってよいものかと思って
質問した次第です。
>>846 よくわかんねーけどさ
void test(){ /*...*/}
main(){
test();
}
これじゃだめなんか?
template関数を呼び出さずに実体化させる方法ってあります?
あります。
>>856 template<class T> void hoge(T) {...}
void (* const hoge_int)(int) = hoge<int>;
こんなんでイケるよ。
>>859 あくまで一例だよ。あ、ごめん君の頭じゃ応用が利かないから
ちゃんといろんなパターンを提示しなきゃわからなかった?
>>858 ありがとん。早速使ってみる+教えるよ。
さらに色々あるんですか、もし良かったら教えてください。
>>862 ググれ!世界にはこういうトリックを紹介しているページがゴマンと
ある。
さて、
template void hoge(int);
で十分なわけだが、
>>860の言う「いろんなパターン」が見てみたいな。
>>867 ライブラリを作っていてインスタンシエーションを細かく制御したいときってのはどう?
>>868 テンプレートライブラリでソースを公開したくないとか? それは限りなく価値がないと
思うが……
870 :
デフォルトの名無しさん:03/09/17 08:59
データベースっぽく扱えるコンテナってあります?
undefined reference to データベースっぽ
スライムベスっぽく扱えるコンテナってあります?
boostのsignal/slotって、チュートリアルでBCCで使えるとか書いてるのに、
1.29.0から1.30.2全部落としてもどれもコンパイル通らない。
ナゼに。
876 :
デフォルトの名無しさん:03/09/18 01:49
長い文字列を扱うことができるという ropeの使い道がよくわからないのですが、
構造的にはstringと どの様に違うのでしょうか。
使ってみればわかる
早い話がvectorとlistの違いのようなものらしい
>>879 違わなきゃ個別に存在してる意味ないだろ、そりゃあ。
string : ひも
rope : ロープ
なのかなー
細かいことだが、
string : 糸
Rope : ひも
ではないのか
>>882だろ。
fiber : 繊維
thread : 糸
string : 紐
rope : 綱
885 :
デフォルトの名無しさん:03/09/18 10:54
ポインタを所持するシングルトンでこんなん書いてみたけど、大丈夫でしょうかね?
//hpp
class Singleton : boost::noncopyable {
public:
friend Singleton& theSingleton(void);
void run();
private:
Singleton();
public://privateにしたいぜ!!
~Singleton();
private:
typedef boost::scoped_ptr<Singleton> SelfPtr;
static SelfPtr instance;
};
//cpp
Singleton::SelfPtr Singleton::instance( new Singleton() );
//not inline
Singleton& theSingleton(void){
return *Singleton::instance;
}
Singleton::Singleton(){
cout << "Singleton()" << endl;
}
Singleton::~Singleton(){
cout << "~Singleton()" << endl;//ブレークポイントかけときゃ止まる。表示されないけど。
}
void Singleton::run(){
cout << "Hello" << endl;
}
うっほ。
コンストラクタで例外だしたらキャッチできないぜ。
やっぱ気にするべきでしょうかね?
やっぱ、気にしないと激しくだめっぽいですね。
明示的に取得、開放するしかないのかな・・・。
lokiはいまのとこ使う予定ないし・・・。
>>887 TABが消えちゃいました、すいません。
まー、なんつーか、普通にインスタンス作るほうでいきますわ・・・
コンストラクタ改良
Singleton::Singleton(){
cout << "Singleton()" << endl;
throw std::exception("例外");
}
//main.cpp
int main(){
try{
Singleton& singleton = theSingleton();
singleton.run();
}
catch(std::exception& e){
std::cout << e.what() << std::endl;//さっきのソースだとここにこない
}
return 0;
}
"string"を「文字列」という意味に解釈するのはこの業界の
人間だけという事実を今はじめてしって愕然としていまつ。
普通はギターとかの弦だよね。
>>882-884 SPACE ALCの結果
string
【レベル】3、【発音】stri'η、【@】ストゥリング、ストリング、【変化】《動》strings | stringing | strung
【名-1】 ひも、弦、糸
・ I tied up the gift using some old string. : 古いひもを使ってプレゼントをくくった。
【名-2】 列
【名-3】 《植物》筋、繊維{せんい}
【名-4】 《コ》文字列{もじれつ}◆【同】character string
【他動-1】 ~に糸をつける、~をひもで吊るす
【他動-2】 ~を一列{いちれつ}に並べる、ひと続きにする
糸でもあるし、紐でもあると。
なんか別のハンドルが…
>>890 つい感覚的に忘れそうになる、ってんなら俺も同じだけどね。
音楽業界だとまず間違いなく「弦楽器」ですな。。。
どうでもいいけど
export を実装していると評判の "comeau" は何て呼ぶもんすか?
コミュー? コメァウ? コメウィアゥェオウァ?
>895
こもー
>>896 サンクスコ ヽ(´ー`)ノ コモー!
ていうか,あえて面白い呼び方を考えてみるテス㌧。
コ・・こm・・・・・
boostのMLなんか眺めていると、米国人はcomoって略記してたりするね。
895を採用。今後はコメウィアゥェオウァで。
901 :
デフォルトの名無しさん:03/09/18 14:27
コメウィアゥェオウァは意外とboost動く率が低いよね。なんで?
boostが嫌いだから
気が付いたこと
#include <iostream>
#include <boost/lambda/lambda.hpp>
int main(){
int i=1,j=2;
using namespace std;using namespace boost::lambda;
//(cout << _1 << "+" << _2 << "==" << _1+_2 << endl)(i,j);
(cout << _1 << "+" << _2 << "==" << _1+_2 << static_cast<ostream &(*)(ostream &)>(endl))(i,j);
return 0;
}
上のはostream & endl(ostream & )とwostream & endl(wostream &)の2つがあってコンパイルできないようだ・・・
コンパイラの制限かと思ってた、今まで(^^;;;
templateの実装ってVCはどんな状況?
.NETになってからどうなったか教えてください
>>905 ということは、部分特殊化などは通らないということですか。
一度Lokiを使ってみたかったんだけれども、boostが通るだけでも良しとするか…
レスサンクスです
つーか、boostが通る==boostのテストでエラーが皆無というとても偉いことなのだが。
いいやboostが通るコンパイラなど体制に屈した軟弱ものだ
>>907 って事はテンプレート関係はかなり実装されているのか。知らなかったtxh
>>911 つーか最強ですよ。
とはいってもあくまでも7.1(.NET2003)の話だからね。
ひとつ前のを選ばないように。
>>912 7.0でした。鬱。アップグレードサービスなんてないだろうな。
2002から2003は無料アップグレードでメディアが送られてきたろ?
ナニヲイッテルンダヨ
wareだから(´∀`)
>>915 氏ね
ついでに7.1はny2で流れてる。MSDNの最新版も必要だから気をつけな。
いや、俺は VS 使ってないよ(;´Д`)
>>913 が CD 知らないようだったから ware じゃねーの?と。
すみません。
std::map<Key, T>なんですが、順不同でinsetした状態のmapでも、
イテレータで巡回する際にKeyのoperator < によってソートされていることは
どのSTLでも保証されているかどうかわかりますか?
つまり、 j が i の次の要素をさすイテレータのとき、
i->first < j->first は成立するか? ということです。
// ただし i も j も end() と等しくはない
手元のVCのSTLではとりあえず確認できましたが、
これがVCのSTLがたまたまそういう実装なのか、
それとも標準でそうすべしと定められているのか
気になっているのですが…
検索効率の点からソートされるのが普通だが、
実装上の定義に含まれていない以上保証などあり得ない
なるほど、そうでしたか。ありがとうございました。
>>919 キーの順にソートされていないとすると、
lower_bound()やupper_bound()が意味を持たなくなるのだが、
その辺はどう考えている?
922 :
デフォルトの名無しさん:03/09/19 17:38
>>918=920
心配するな。規格で保証されている。
23.1.2 Associative containers の 9項だ。
The fundamental property of iterators of associative containers is that they
iterate through the containers in the non-descending order of keys where
non-descending is defined by the comparison that was used to construct
them. For any two dereferenceable iterators i and j such that distance from
i to j is positive,
value_comp(*j, *i) == false
おおお。規格で保証がっ。
これで安心してソートされてる前提でプログラミングできます。
答えてくださった皆様どうもありがとうございました。
>914
得?
うちには着てないぞ????
>>914 そんなん送られてきていませんが…
特別ライセンスなので違うのかな。MSに問い合わせてみます
>>925 少なくともAcademic版はアップグレード対象外。
>926
ソレダ(´・ω・`)
VC7.0を使っています。
template <class X,class Y> struct sample;
template <class X> struct sample<X,int>{};
上のコードが通らないのですが、これはVCがサポートしていないのですか?
それとも構文ミスでしょうか?
>>928 してない。VC++.NET 2003買って。
テンプレートの特殊化の文法がいまいち自信ないので教えてください。
今私は、LokiのTypeListのみを使うテンプレートを書きたい場合、
template <class T> SomeClass;
template <class X,class Y> SomeClass<TypeList<X,Y> > { ... };
実際にクラスの内部でXやYを使っていないにもかかわらず
(同じTypeList<X,Y>を別テンプレートにそのまま投げているだけ)
上のように宣言をしているのですが、これを素直に書く方法はありますか?
>>931 何がやりたいかわからないけど結論はない。
あえていうなら
template<template<class,class>class TList = ::Loki::Typelist>
class SomeClass
{
public :
typedef TList<std::string,int> Type;
};
こんなの。
>>932 ありがとう。その書き方も知らなかった。
具体的にやりたいのは、
template<template<class,class>class TList = ::Loki::Typelist<SomeType,SomeType> >
class SomeClass
{
public :
typedef TList Type;
};
こんなのをやりたいんですが、冷静に考えれば不可能ですね…
>>933 何がやりたいのか良くわからない。
つまり、
SomeClass< Loki::Typelist<T1, T2> >::Type // == Loki::Typelist< T1, T2 >
SomeClass< SomeType >::Type // コンパイルエラー
SomeClass< OtherTypelist< T1 > >::Type // コンパイルエラー
みたいにしたいのか?
だとしたら、簡単な特殊化で実現可能。
テンプレートの特殊化のサンプルなら、
Loki::TL::*, Loki::FunctorImpl, Loki::TypeTraits みて理解を深めるべし。
>>934 こんなんは
template<class TList>
class SomeClass
{
template<class TL>class Check;
template<class T,class U>
class Check<Loki::Typelist<T,U> >{};
// Typelist適合検査
enum { dummy=sizeof(Check<TList>) };
public :
typedef TList Type;
};
>>934 そう、そんな感じです。
で、実際に使うときに、わざわざ使いもしない型T1、T2をコンパイラに指定するのは
無駄のような気がしたので、もしかしたら特殊化以外に方法があるのかと思いましたが、
T1とT2の型をコンパイラに伝えるのは全然無駄ではなかったですね。むしろないと処理できない。
templateによる汎化について詳しく書かれた本は
Modern C++ Design以外にないのでしょうか。
洋書でも構わないので進言願います。
>>938 C++ Templates: The Complete Guide
Modern C++ Designのどこが気に入らなかったのか知りたいな
>>939 どもです。読んでみます。
>>940 むしろ気にいったのでもっと掘り下げたいなあ、と。
継承よりtemplateで汎化した方が良い例をもっと見てみたかったので…。
>>941 > むしろ気にいったのでもっと掘り下げたいなあ、と。
それなら、C/C++ Users Jounal を定期購読するといいんでないか?
あーそういや今月号届いてないような。おかしいな・・
>>943 おお、どもです。
C++ Reportなぞも取ってみたいとは常々思っているのですが、
海外の雑誌ってネットから申し込んで
簡単に定期購読できるものなのでしょうか?
…と、ここまで書いて己が教えて君であることに気付いてしまったので
回線切らずに検索してきます。失礼しました。
ウメ
947 :
デフォルトの名無しさん:03/09/24 13:24
>>947 …… って落ちついて見れば、そんな巨大でも無いな。
lamda とか、mpl とか使っているから、やたら理解し難いけど。
949 :
デフォルトの名無しさん:03/09/24 13:54
950 :
デフォルトの名無しさん:03/10/03 21:27
メタプログラミングっていつどのようなときに使えばいいのかわからない。
もだーんC++デザイン読んでない俺にもわかるように熱く語ってくれぃ。
田舎にゃーうってないんだよな・・・、どの本屋いっても糞ナ本しかうってない・・・。
アマゾンに個人情報さらすしか手段ないのか・・・。
952 :
デフォルトの名無しさん:03/10/05 16:37
>>950 MPL、LOKIなんて飾りです。偉い人にはそれが分らんのです。
漢はCでのマクロプログラミングです!
>>952 じゃ~、何であなたはこのスレ閲覧してんの?
>>953 C++でマクロプログラミングをするには、
対象言語としてのC++が複雑すぎるんです。
>>954 まぁでも、boost::preprocessor は便利に使わせてもらってるよ。
C でも boost::preprocessor 使ってますですよ。
// いや、仕事とかじゃないし(´∀`)
template <bool hoge=true>
struct DefalutArgs{
typedef int type1;
typedef char type2;
typedef double type3;
typedef float type4;
};
template <>
struct DefalutArgs<true>:public DefalutArgs<false>{
typedef unsigned int type1;
typedef unsigned char type2;
};
template <typename T=DefalutArgs<>::type1>class Test{
};
int main(){
std::cout << typeid(DefalutArgs<>::type1).name() << std::endl;
std::cout << typeid(DefalutArgs<>::type3).name() << std::endl;
return 0;
}
ふと思いついた、後で変更可能なデフォルト引数。
上書きしなければ初期値もそのまま使える。
>>958 なんとなくはやりたいこととその仕組みはわかるんだけど、
いまいちピンとこないのでもっとわかりやすい命名規則でおながいします。
( 特に hoge なんてサイテー。 )
へぇ~、デフォルト引数って特殊化出来たのね。
でも変更しようと思ったこと無いからな。
変更したらデフォルトの意味がなくなるような気がするし。
そろそろジスレを立ててもいいかな?
良いと思いまつ。
しかし、spiritはなんで先読みじゃねーんだよヽ(*`Д´)ノ
セマンティックアクションが書きにくいったらありゃしねぇ
それがspiritの魂なのさ!ウヒョヒョアヒャヒャヾ(゚∀゚)ノ
誰か、「次スレ」のリンク貼れよ。
低レベルな質問でもうしわけないんですが、
通常のiteratorとreverse_iteratorのどちらも代入できて
インクリメントなどが適切に動く型ってないんでしょうか?
この2つを共用体でまとめて、判別用のbool値と
いっしょにまとめた構造体を作るとか
あるいは実行時型付けとかしないといけませんか。
すみません。
今、ある地点クラス
class Point
{
int x;
int y;
...
}
を1次元に並べて
typedef list<Point> Path
のような経路クラスを作ってます。
その上を往復するように移動する人クラスを
class Walker
{
Path* ptr_path;
Path:const_:xxxx_iterator itr;
...
}
のように用意して、
経路をpathの順方向に辿るときと逆方向に辿る動きを実装するのに
iteratorを使いたいんです。
>>968 ++で進んで--で戻れ。
…ってことではなく?
ああ、説明不足でしたね。
「向き」の情報は別に持っていて
その向きにあわせて「”前”に進む」メソッド、「”後”に戻る」メソッド
を呼び出す形で扱いたいんです。
先に書いたように、
bool値で向きの情報を持っておいて
処理を分岐させれば一応
望むものはできるとは思うのですが……。
iteratorが辿る向きによって2種類存在するなら
それを利用できないものかと欲を出しているのですよ。
どうも私の想定しているやり方ではできないという前提で
考えてくださっているようなので、
単純化した例ではない全体をさらしておきます。
次スレ準備のためにレス数不足のようでしたらおっしゃってください。
今スレでは質問を控えさせていただきます。
まず、一つのPathの上で複数のWalkerが動きますので
Path自体をreverseさせるのは無理です。
さらに、移動する経路というのも、実は単なる一本道の往復路でなくて、
上に示したところのPathが複数とそれらが複数つながったノードで
構成されるネットワーク構造になっているのです。
(首都圏の電車の路線図などを想像してください)
で、このネットワーク状マップの上をwalkerが動くわけですが、
自らの進路を完全にPointの集合で持つのは無駄ですので、
一直線上にPointが並んでいて分岐がない部分はPathという形でリスト化し、
さらにその集合で進路を表す、という方針で作成しているのです。
が、そうするとそれぞれのPathにおいて進む向きの
情報をどう持つかが微妙なことに~という状態なんです。
かなり崩壊気味の日本語を書かれる方ですね。
何が言いたいのかさっぱり分かりません。
つーかSTLのソース読めばいいのに
すみません。
もう少しSTLの勉強と実践してみます。
わざわざありがとうございました。
そもそもendとrendをどうやって使い分けるつもりなんだろう…
>>974 そういう時は男は黙ってboost::graph。
でも、reverse_iteratorとiteratorを変換したくなる事はあるなぁ。
何か一発で変換できたりするのかな?
emptyでないことがわかってる時、最後の要素を取ろうと思って
毎回end()を--するのは結構嫌だったり。
> でも、reverse_iteratorとiteratorを変換したくなる事はあるなぁ。
> 何か一発で変換できたりするのかな?
reverse_iteratorのコンストラクタとbase()メソッドでは?
>>977 > emptyでないことがわかってる時、最後の要素を取ろうと思って
大抵のコレクションで、最後の要素への参照を返す back() が提供されてると思うぞ。
end()って--していいの?
>>978 ソレだ!ありがと~。
>>977, 978
すみません文章が悪かったです。
「最後の要素を押さえたくて」なので、referenceだと都合が悪かったり。
listの尻を押さえておく場合とか。
>>985 反復子を逆反復子にする時、またはその逆の時は一つだけ注意が
必要。
1 2 3 4 5 6 7 8 9 10 という std::vector<int> があったとすれば、
std::vector<int>::iterator pos が 6 を指している時
std::vector<int>::reverser_iterator rpos(pos) としたら rposは
6を指さず5を指す。
これはrbegin()がend()と同じ場所を指すようにするための配慮で、
reverse_iteratorは常に一つ戻った場所の値を取り出す。
同様に
std::vector<int>::reverse_iterator rpos が 5 を指しているなら
std::vector<int>::iterator pos(rpos) で pos は 6を指す。