1 :
v(^・^)v :
2011/02/08(火) 14:16:35
2 :
v(^・^)v :2011/02/08(火) 14:18:09
3 :
v(^・^)v :2011/02/08(火) 14:19:25
4 :
v(^・^)v :2011/02/08(火) 14:20:22
5 :
v(^・^)v :2011/02/08(火) 14:21:07
6 :
v(^・^)v :2011/02/08(火) 14:21:49
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。 ------------------------------------------------- テンプラ終わり(・∀・)
ある二つのクラスでのみ使いたい定数がある場合にその定数はどう管理するのがいいの 定数だけ定義されたクラスを作ってクラス名::定数名でアクセスするのがいいの
8 :
デフォルトの名無しさん :2011/02/08(火) 14:50:13
>>7 一つ目のクラスでprivateでstatic const で定義し、二つ目のクラス用にそれをfriendにする
定数ならヘッダにでも書いとけばいいじゃん
これでもいいのでは class Test2; class Test1 { static double d; public: friend class Test2; static void printd() { std::cout << d << std::endl; } }; double Test1::d = 1.23; class Test2 { public: void printd() const { Test1::printd(); } }; int main() { Test1 t1; Test2 t2; t1.printd(); t2.printd(); }
C++で音楽を再生したいのですが良い方法はないでしょうか? ARを用いてWEBカメラで対象のマーカーを認識したのちに出力といった形にしたいです。 形式としては、メモリに最初読み込んで、マーカー認識時に音楽再生 現状は #include <mmsystem.h>と、リンカで Winmm.lib を追加しています。 プログラム的には、 int main(void)内に、 PlaySound("testfile.wav",NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); で再生し、PlaySound(NULL, ,NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); で停止させています。 DirectXのLoadSoundMemを使えば、一行で済むのですが if( DxLib_Init() == -1 ) return -1; // 初期化 DirectX初期化時に黒枠ウィンドウ(CMD)が残るため、使い物になりません。 良い方法ないでしょうか?
SND_MEMORYじゃダメなの? なんでそんなめんどくさいことしてるのかわからん
>>12 SND_MEMORYちょっと調べてみます、サウンド系はDirectXでしか触ったことないので
ググッても中々…
>>13 一応ARはC++で作成するものですので(他にもありますが)
該当スレかと
>>12 SND_MEMORY調べたときにsndPlaySoundも見つけ上手く出来ました感謝。
sndPlaySoundA((LPCSTR)lpSound,SND_ASYNC|SND_MEMORY);
すみません std::uninitialized_copyを見て思ったのですが コピーの途中でコピーコンストラクタが例外を投げて、コピーが中断したら 途中までコンストラクトされた要素はデストラクトされるのでしょうか? もしデストラクトされない場合は、try-catchで捕捉してデストラクトする などの処理が必要でしょうか。
デストラクタは呼ばれるから気にしなくていい
18 :
16 :2011/02/08(火) 17:36:11
>>17 ご教示ありがとうございます。
なるほどデストラクタは呼ばれるのですね。勉強になりました。
>>14 それはDirectXじゃなくてDXライブラリだって話もあるが、
そもそもAPIの話は該当スレに行けと言ってんだよ
誰がDirectXとDXライブラリを混同してんの? つっこむなら、DirectXでやったことあるならわざわざDXライブラリ経由しなくていいじゃんって方向じゃないか?
shared_ptrと同じ機能で、アクセスするときに*演算子がいらないようなスマートポインタはありませんか?
>>21 一般的なポインタのルールにのっとってそういう感じになってるわけだからねー。
operator.()ができないからC++では不可能 つか、 shared_ptr<T>ptr; ptr.use_count()でshared_ptr<T>::use_count()を ptr->use_count()でT::use_count()を呼び分けてるのは分かってる?
template<class T> class Test { public: void test2(T* pTest) {} void test1() { Test<Test<T>*>* pTestTest = new Test<Test<T>*>(); pTestTest->test2(new Test<T>()); } }; Test<int> test(); test.test1(); このコードをコンパイルすると pTestTest->test2(new Test<T>()); の箇所で 「1 番目の引数を 'Test<T> *' から 'Test<T> *' に変換できません。」 とコンパイラに怒られてしまいます。 型解決が無限ループとなっている(?)のが原因だと思うのですが、Testクラス外でtest1を定義する以外に解決方法はありますでしょうか? よろしくお願いします。
Test<Test<T>*> の場合 test2 の引数は Test<T>** だから new Test<T>*() ならいけるんじゃない
こんな感じか gcc4.5.1(MinGW + Eclipse CDT)で実行済 template<class T> class Test { public: void test2(T* pTest) { if (!pTest) return; std::cout << "test2()" << std::endl; } void test1() { Test<Test<T>*>* pTestTest = new Test<Test<T>*>(); pTestTest->test2(new Test<T>*()); } }; int main() { Test<int> test; test.test1(); int i = 0; test.test2(&i); }
>>25-26 単純に型の指定ミスだったとは…
おかげさまで解決しました。ありがとうございました
29 :
28 :2011/02/09(水) 23:49:07
よく見たら説明になってない。 テンプレートの型指定子に毎回異なるものを入れると並列化されるみたいなんだけど、 これは環境依存になるのかな? って書けばよかった。Orz
>>29 ちゃんと見てないけど型にしろ定数にしろ
template に渡すものが違えば別の型になるよ。
31 :
28 :2011/02/10(木) 12:53:40
>>30 レスさんきゅー。一応、大丈夫そうだね。
何か機会があったら活用してみたいとおもいますー。
LinuxでC++やってます。 別スレッドから、親スレッドのGUI部品にアクセスするには、どういった手法があるのでしょうか?
同期します。
>>11 もそうだけど、C++使って○○の開発をやってるからって、○○の質問をここでするなって。
○○相談室じゃないんだから。
35 :
32 :2011/02/12(土) 11:40:57
>>33 すみません。別スレッドは常に特定の通信用ポートにバインドされていて常時Listen状態で、基本的に終了しません。
必要なログ情報を、メインスレッドのリストボックスに吐き出していく仕様です。
キュー
37 :
32 :2011/02/12(土) 12:28:39
>>36 キューも考えました。
子スレッドからキューに書き込んで、メインスレッドからキューを読み込む。
でもメインスレッドを、キューを読むループ状態にしてしまって、GUIイベント処理って可能でしょうか?
C#だとデリゲートがあるけど、デリゲートがない言語だとどうやって実装してるのでしょうか。
キューでもイベントでもなんでもいいよ。 とにかくUIスレッドのメッセージループと同期しなきゃ始まらんだろ。 同期方法はGUIライブラリが提供してるからドキュメント読め。 C++でスレッドは規格外だからC#みたいな標準的な方法なんてのはないよ。 だからスレ違い。
>>37 デリゲートってスレッドで実装されてんじゃないの?
わたしたちのデリゲートゾーンの悩みに。
デリゲートは関数の動的型付けだよ
は?
メンバ関数ポインタを、テンプレートクラス内のクラス(イテレータのようなもの)のメンバ関数に渡そうとして躓きました 以下のような感じで「型"void (test2::*)(aaa&, test<aaa>::iterator)"の引数は型"void (*)(aaa&, test<aaa>::iterator)"のパラメーターと互換性がありません」というエラーが出ます どうすればメンバ関数を関数に引数として渡せますか? Visual C++ 2010使ってます //test.h template < class T > class test { public: class iterator { public:void yobidashi( void (*function)( T&, iterator ) ){} } } //hoge.h #include <test.h> struct aaa { ・・・ } typedef test<aaa> testaaa; //test2.h(実際はヘッダとソース分けてます) #include <hoge.h> class test2 { private: void func( aaa& a, iterator ite ) {} public: void zikkou(){ testaaa::iterator ite; ite.yobidashi(func); } }
方法1. std::bind と std::function を使う //test.h template < class T > class test { public: class iterator { public:void yobidashi( std::function<void ( T&, iterator )> function ){} } } //hoge.h #include <test.h> struct aaa { ・・・ } typedef test<aaa> testaaa; //test2.h(実際はヘッダとソース分けてます) #include <hoge.h> class test2 { private: void func( aaa& a, iterator ite ) {} public: void zikkou(){ testaaa::iterator ite; using namespace std::placeholders; ite.yobidashi(std::bind(func, _1, _2)); } } 方法2. void func( aaa& a, iterator ite ) {} -> static void func( aaa& a, iterator ite ) {} に変更
ite.yobidashi(std::bind(&func, this, _1, _2)); だった
>>45-46 標準だと &func じゃメンバ関数へのポインタにはならないよ。 VC++ だと通るみたいだけどね。
&test2::func って書かないと。
てかそもそも
>>44 は関数ポインタとメンバ関数ポインタの違い分かってるのかなぁ。
メンバ関数ポインタはthisも渡さないと意味ないよね
50 :
44 :2011/02/16(水) 14:19:11
>>45 方法1だと
void yobidashi( void (*function)( T&, iterator ) ){}
void yobidashi( int (*function)( T&, iterator ) ){}
void yobidashi( void (*function)( T& ) ){}
void yobidashi( int (*function)( T& ) ){}
みたいにいろいろ用意したいときできないようですし
方法2だとtest2::funcにおいてthis->・・・のようなアクセスができないようです
すいません普通の関数ポインタと同じ程度に考えていたのでここまでいろいろな制約ができると思わず詳しく書きませんでしたが
様々な関数型で呼び出しできてthis->・・・でアクセスすることもできる方法はないでしょうか
なんでイテレータにyobidashiなんてものが必要なのかよくわからない zikkouでイテレータからTを得てfuncを呼び出すんじゃいかんのか
yobidasiをテンプレートにするとか。
>>51 将棋盤のような8方向に移動できる連結リスト構造を作っていて
イテレータで直線的な移動はできるのですが周りの8マスに同じ処理するときは関数呼び出しで効率よくできないかと思いまして・・・
>>52 もう少し詳しく教えてもらえないでしょうか
void yobidashi( std::function<void ( T&, iterator )> f ){} void yobidashi( std::function<int ( T&, iterator )> f ){} void yobidashi( std::function<void ( T& )> f ){} void yobidashi( std::function<int ( T& )> f ){} でいいじゃん
template <class T> yobidashi(T t) でもいいじゃん
>>54 それだとbindで関数渡そうとしたとき複数のインスタンスが引数リストと一致しますてなってうまく判断してくれません
>>55 理解力がなくてすいません
それは何をしようとしているのかもう少し詳しく教えてもらえませんか
>>53 こんな演算子作って、複素数で好きな方向に進めるように指定したらどう?
iterator& operator+=(const complex<int>& direction)
>>53 イテレータからTを得てfuncを呼び出すんじゃいかんのか
static task() { 時間のかかる処理 } static func() { task(); } main() { CreateThread(NULL, func…); CreateThread(NULL, func…); } この時、task内のローカル変数って、一つ目と二つめのスレッドで独立しているのでしょうか? ふと迷ったのでよろしくお願いします。
>>59 スレッド関連はいまのところ実装依存。
自動変数にスタックを使う典型的な実装では、 static と指定しない限りは独立したものになる。
59は関数に対するstaticを何か特別なものだと思ったんじゃなかろうか
独立してなかったらほとんど使い物にならないと思うが...
atomic みたいなキーワードが追加されて、スレッド間で共有されるアトミックな変数が宣言できるようになったら便利じゃねーかと一瞬思った atomic int count; みたいな
アトミックな変数って何? その変数を使った処理はすべてアトミックに処理されるってこと?ならずいぶんワイルドである。
compare-and-swap演算子がないといまいち
count %= 2; 軽く死ねるな
67 :
デフォルトの名無しさん :2011/02/19(土) 05:03:05
以下のような、「あるオブジェクトへのポインタを保持する機能」を
テンプレートクラス化したものを作ってみたんですが、VC2008Expressでは通るものの
Codepadやideoneに貼るとエラーになりました。
http://codepad.org/aB4RFpdY 色々いじってみたんですが、なぜエラーになるのかよくわかりません・・・
>>67 const Derived *p = static_cast<const Derived *>(this);
const has_dependency_pointer<typename T::__base_t> *dp = p;
return *static_cast<T *>(dp->m_pDependingObject);
69 :
67 :2011/02/19(土) 09:51:10
ありがとうございます! ベースクラスのメンバを::でアクセスするのがダメだったんですね。 テンプレートの解析周りとも絡んでるのかな・・・調べてみます。
70 :
67 :2011/02/19(土) 11:21:21
どうやら構文解析が追いつかなくなっただけだったようです、
>>68 のようにポインタを介すか、もしくはmain関数内で
lexical_castにGetDependingObject()の戻り値を直接渡さず
変数を介して渡せば大丈夫でした
>70
Derived:: 外せば通った。
http://codepad.org/vizevSF9 コンパイラさん的には Derived の中身を知らない段階で Derived::has_dependency_pointer が何かを知る必要があるんだけど、
何も付けないとメンバだとして認識され、typename 付けると型として、template 付けるとメンバテンプレートとして認識される。
今回そのどれとも違う(has_dependency_pointer<...> で型として認識させたい)けど出来なさそう。Derived 外して通るしね。
72 :
67 :2011/02/19(土) 13:59:13
あああすみません、70で大嘘書いてました、仰るとおりDerived::のせいだったみたいです・・ いつのまにかDerived::外してましたorz コンパイラの解析順序は勉強不足でわからないんですが、 DerivedのポインタなのにDerived::で型指定は明らかにおかしいですね。外したらlexical_castに直接渡そうが大丈夫でした。 ありがとうございました。
73 :
71 :2011/02/19(土) 14:17:07
74 :
67 :2011/02/20(日) 05:30:54.89
なるほど・・・、C++03で?一応合法ではあるんですね<VC2008で通る ありがとうございました。
あんまり込み入ったやり方より平易で確実な書き方をする方がよい。
名前空間について教えてください。 - a.h - namespace NS { class A {}; extern A a; // aを使って何かする } - a.cpp - #include "a.h" using namespace NS; A a; int main() { a; return 0; } ↑のコードではaが曖昧だとしてコンパイルエラーが出ます。 これについてのC++の仕様などが説明してあるようなところがありますでしょうか?
>>76 NS::a と ::a の2つ宣言して、 using namespace NS したらどっちかわかんなくなるのは当然だと
思うんだけど、それ以外に何か説明が要るの?
>>77 つまり
NS::A NS::a
と、
NS::A ::a
の違いってことでしょうか。
usingディレクティブではインスタンス側には適用されないということですか?
usingディレクティブが良く分かっていません。
>>79 ありがとうございます。
おかげでようやく意味がわかりました。
usingディレクティブの意味を誤解していたようです。
上のコードを見て実験してみたんだけど namespace A { int x = 1; } using namespace A; extern int x; // 問題の行 int x = 2; int main() { std::cout << x << "\n"; } "問題の行"がある時はあいまいエラー、 ないときは::xがA::xを隠蔽して正常動作。 "問題の行"の x はどっちの x を指してるんじゃろ?_?
初期化を行わない vector が欲しい C++ はゼロオーバーヘッドの原則が〜って言われるけど、 malloc で組んでた動的配列を std::vector に置き換えることはこの原則に反しないの? std::vector<int> が領域確保後にゼロクリアするオーバーヘッドは無視できないと思うんだけど 何か勘違いしてるかな…
class T { public: T():x(0),y(1){} union { int x; int y; }; }; こういうのは問題ありますか? unionの初期化はどうするのが一般的でしょうか?
>>86 BCCです。
codepadではエラーだったのですが、BCCでは通りました。
必ずエラーになると定義されていてBCCがおかしいのか、
定義されていない動作なのか分からなかったので。
それでなにかしたかったわけではなく、単純な疑問です。
BCCだと初期化後の値は1でした。
>>87 順番に評価されるから 1 になるのを期待するのはわからんでもないけど、
それなら y(1) だけでいいじゃない、っていう。
>>88 単純な疑問です。
宣言と実体を別に書いた場合、この x は初期化してたっけ?っていうのもあると思いますし。
>>85 それってメモリ確保するだけで、
resize したときにゼロクリアされるでしょ
resizeとreserveは違うぞ 勘違いしてないか?
>>83 ,91
まさか不定な値を使いたいわけじゃないんだよね?
どんなケースを想定してるのか具体的な例を出してもらわないと伝わらないかも。
いや、分かってるって 例えば 1MB のファイルを読み込みたいとして、1MB の領域を確保して使いたいとするじゃん こういう場合どうする?resize するしかないよね?これだとゼロクリアが入ってしまってそれが無駄。 ゼロクリアの処理を回避して確保する方法ってある? これだけなら new unsigned char[1024 * 1024] でいいけどさ、malloc / realloc や std::vector と違って後で拡張できないじゃん。
reserveしてmemcpy(&v[0], 1Mのファイル);ってするな
>>94 なるほどね。
うまい方法は無いかなぁ。
特殊化の穴をつけばいけるかもしれないけど、特定の実装に依存したものにしかならないだろうな。
コンテナに不定値はないんじゃないの ゼロクリアがいやならinsertで初期化すればいい それもいやなら……どうすればいいんだろうな
boost::scoped_arrayを使う。 予めサイズがわからないなら諦めてvectorでresizeする。どうせオーバーヘッドとしては 大したものでもない。
>>99 > C++ はゼロオーバーヘッドの原則が〜って言われる
Cと同じ処理をするにあたり、上記原則を満たさない場合があるってことでいいのかな
確実な初期化をオーバーヘッドと見るか機能と見るかって違いじゃないの? 未初期かなのが欲しければ malloc() すりゃいいんだし。
取り違えがあるぞ。そもそも Container の主たる役割はメモリ確保でない。 メモリ確保を行うのは Allocator の役割だ。
で?っていう
不定な状態のまま存在するというのは コンストラクタも呼ばていないのにアクセスは可能でコピーできる それでいて不定値ならばデストラクタを呼んではいけない そんなコンテナは設計が難しすぎる
不定値ならばデストラクタを呼んではいけないというのは初めて知った。規格?
いや規格で決まっているわけじゃないけれど コンストラクタが呼ばれないのにデストラクタが呼ばれるのは何か変ではないかと
だからさ。そんなに未初期化領域が欲しけりゃ std::allocator でも Boost.Pool でも好きなの使えよ。
コンストラクタ内で初期化されるから、vectorはmallocの代替にはならない
コンテナにアロケータの仕事のみをさせるのはそもそもおかしい
などとかいていたら
>>107 が颯爽と
malloc()の置き換えはnew[]でしょ。 オーバーヘッドを許さないならrealloc()で拡張なんてできない。 > C++ はゼロオーバーヘッドの原則が〜 これってC++の言語仕様を決める奴らの指針でしょ。
reallocと同程度のオーバーヘッドで、ということかと。 拡張だけですむなら拡張を、無理なら別のアドレスに確保をという挙動
初期化しない以外は標準コンテナなvector欲しくなるよね。 俺は自作してるよ。
俺が欲しいのはboolが特殊化されていないvectorだな
deque<bool>で。ぜひ。
vector<bool>を使いたいのに仕方なくdeque<bool>とタイプするたびに これを承認したやつの髪の毛をむしりたくなるよ
無残に禿散らかすよりはいっそすべてむしり取ってあげた方が親切というもの
どうせ適当な値で上書きするんだから初期化が無駄ってことならサイズ 0 にしといて assign じゃあかんの?
コピーもしたくないってこと。
>>117 よく分からん。
未初期化な部分への代入か未初期化な部分へのコピーコンストラクトかの違いになるだけじゃないの?
ファイル読み込みはただの例で、それに限らず、未初期化の配列に大量のデータを書き出す C スタイルの関数と組み合わせて使いたいって話だろう。
再帰関数で引数以外の変数を静的スコープで解決したいんのですけど、 クラスにしたくは無いし、引数を多くしたくないんですけどどういう解決策がありますか? ラムダ式は再帰できないのでわかりません。 引数を構造体にしたらどんな関数も引数一つで十分ですか?
>>121 静的変数使えば?
最後の質問は、関数の仕様によるとしか言えない。
なるほど、静的変数は思いつきませんでした。 静的変数は関数を始めに実行するときに初期化されて 終了するまで存在し続けるのですよね。
>>120 そうです。例えばsocketからのrecvとか。
ファイルI/Oにしろソケットにしろ、メモリクリアのコスト以上に掛かるんじゃね?
>>125 データ読込は無駄なコストじゃないから。
無駄なメモリクリアやメモリコピーを排除したいのです。
どうせプログラム全体の速度からしたら、誤差で無かったことになる程度しか変わらないけどね。 毎度のことながら馬鹿の考え休むに似たり。
126はアホ
trivially copyableでないクラスが突っ込まれることもあるvectorにはそういう機能はつけられんなあ
>>127 本当にそうなら楽なんですけどね。
ギリギリの高パフォーマンスを求められるようなケースでは
無駄なメモリアクセスは極力排除したくなりますよ。
パフォーマンス実測で比較した結果として。
ギリパフォが必要ならそもそもベク使う理由なくない? 値わたしが基本のSTLコンにそこまでパフォ求めても。 まるでニュにマロ並みの速度を求めるようなものだよ
130はアホ
>>129 non PODクラスはさすがに初期化しないわけにはいきません。
初期値指定が無い場合デフォルトコンストラクタが呼ばれ
る様にすれば問題ないです。
そんなケースでSTL使うなよC++使うなよC使えよアセンブラ使えよ
>>134 いや、 C++ 使う道具を間違えてるだけで、 C やアセンブラに降りる意味は無い。
>>131 STLコンテナにしたい理由は既存のSTLコンテナ対象のライブラリを
使用したいからというのが大きいです。
newや他のメモリプールをMyStlLikeVectorClassでラップすること
のコストは無駄なメモリアクセスを発生させることに比べれば微々
たるものですよ。特に処理するデータブロックが大きい場合。
C やアセンブラ使うと今度は開発コストが大きくなりすぎるから却下
あほは相手にするな vectorでいいから、使う分をはじめに十分確保しとけ
つまりはSTLはコーディングが楽になるが、実行速度は遅いということだよね。 十分速いのかもしれないが、ある面で見ると遅くなっていることは否めないと。
コンパイルも遅くなるよ!
>>139 「STL」ってコンテナやらアルゴリズムやらごちゃごちゃ入ってるものを指して
「遅い」と断じるのに無理があるのは明らかだろう。
横着せずに「未初期化な配列を使っていたところをstd::vectorで置き換えたら
遅くなることがある」と正確に覚えろ。
vectorは遅いですよね!はC++初学者が通る道
速度低下のかわりに得られるメリットがあると書いてるつもりだよ。 配列の代替手段としてvectorを使うと速度低下を招くことには異論ないでしょ? ある局面においては無駄な処理が行われてしまうことは認めなければならないし、 その速度差が重要な場面では、STLは遅いと断ずることは間違いじゃない。 現に、彼はその無駄な処理の有無によって生まれる速度差が有意なものであると感じてるわけで。 その上で、vectorの利便性を損なうことなく、初期化を省く手法はないのかと尋ねているのでは?
遅い遅いっていうけど体感で言ってるの?
体感w
>>143 > 配列の代替手段としてvectorを使うと速度低下を招くことには異論ないでしょ?
↓
> その速度差が重要な場面では、STLは遅いと断ずることは間違いじゃない。
これが明らかな論理の飛躍だと言っている。
vector についての事実があったとしても、それを以って algorithm や iterator を
含めたライブラリ全体の速度の判断材料にはなり得ない。
いい加減にSTLとかいう妙なくくりを使うのもやめてほしい。
struct BufValue { BufValue() {} char c; }; std::vector<BufValue> buffer; これはコンストラクタがあるからだめなんだっけ?
>>130 >パフォーマンス実測で比較した結果として。
具体的に何をどう比較したんだ?
やりもしないで、いい加減なことを言うのはやめた方がいいぞ。
こんな感じのことをしてるだけだろ for( int i = 0; i < 100000; ++i ) { for( int j = 0; j < 1000000; ++j ) { std::vector<int> foo(1000000); }} Ω<遅い、耐えられん! そりゃ遅くなるよ、としか言えない
>>136 「既存のSTLコンテナ対象のライブラリ」がvectorしか受け付けないのが間違ってる。
「STLコンテナ」ってのはSTLの作法(beginとendの間をiteratorで回せるとか)を満たすコンテナ(当然自作のを含む)であって、特定のクラスではないよ。
よくわかんないな メモリの初期化コストが気になるくらいって そんな大容量メモリ? アーキテクチャ的にメモリが遅い? 前者ならそこそこの速度がありそうだし、 後者ならもっと下のレベルで裏技があることが多いような。 まあ、そんなギリギリな環境で STL 使うなやって思うけど。 STL が悪いって話じゃなくて、事実として、その環境では速度的な問題が出てるんでそ?
何の役にも立たない無駄なところにこだわって開発が進まない奴って本当にクズ。
>>153 俺のことかああああああああああああああああああああ
図星うわああああああああああああ
クズ
メモリアクセスが無駄な初期化+本来のデータ埋めで2倍に なるという明白な事実も理解できないゆとりばかり。
無能がはびこってるおかげで俺の仕事は増えるばかり。
ということにしたいのですね
そもそもメモリの初期化コストがどうでも良いような 案件ならなんでC++使うの?C#でも使えばいいじゃない。
初期化コストとかいってるやつは、 自分のアルゴリズムが複雑怪奇か、何もしてないだけ。 やらなくていいのに毎回メモリ確保してるとか。使い回せばいいのに。
確実にvectorでの確保がホットスポットになって vector使う限りは回避不可能の具体例あげてみろ。
>>156 確かに、その後に続くだろう1万回のメモリアクセスを加味して、
10001回のメモリアクセスが10002回になるなんてとんでもない話だよな
>>161 ホットスポット?
ホットスポット=ボトルネック とおもってくれ
ボトルネックが待ち時間で、 ホットスポットはCPUの処理時間。 CPU処理の集中がホットスポット。
あ・そ・こ
>使い回せばいいのに。
>>162 同じデータを1万回もアクセスしなきゃいけないってどんな場合だよ?
そういう場合なら確かに初期化コストなんて誤差の範囲だね。
だからなんで初期化コストがそんなにかかる案件で vector 使うのさw
つーかたかだかvectorの初期化の速度にガタガタ文句を付ける顧客には Core i7の2600番台を買わせろって そんなにべらぼうに高いわけではないし、最悪待ってりゃ終わる事
そういう問題じゃねえ。 vectorの初期化がボトルネックになるって、くそコードのせいだろ。
へぼコードなんだ。 vector確保しかしていない OR vector確保回数が多く大半
ギリギリの高パフォーマンスを求められるようなケースでrealloc()で拡張なんてしない。new[]でおk。 てか代替する必要がない。malloc()のままでおk。 そもそもクリティカルな所で動的確保するのがおかしい。
ただ単にSTLセマンティックなコンテナ使用による開発効率UPを享受 した上でstd::vectorの無駄な初期化コストを省きたいということな んだが、、、こんな不毛な議論になるとはw 初期化しないカスタムvector自作なんてnew[]を直接使うなんて保守 性の悪いやりかたがもたらす結果に比べれば遙かに楽なことなんだし。
初期化しないカスタムvector自作なんて簡単だわー 二年前から自作してたわー
メモリの初期化命令をあっさり無視する独自のallocatorクラスを記述して それをvectorに渡せばいいじゃないか^^
>>175 当然vectorの全機能搭載済みだよな?
>>173 高パフォーマンスだったら、OSの機能、ハードウェアの機能を直に使えよ。winAPI、アセンブラなど。
>>178 おいおい車輪の再発明はやめようぜ
プログラマも時間と金には限界があるんだぜ
>>179 この部分だけやればOK
> メモリの初期化命令をあっさり無視する独自のallocatorクラスを記述して
> それをvectorに渡せばいいじゃないか^^
そもそも初期値を設定することすらネックになる処理って何? 前提条件を明確にせずに方法論だけ語り出す奴らって、何の役にも立たないクズなんだが。
俺はゼロフィルしてくれたほうが色々ありがたいけどね。 不定値の特定が難しいとデバッグが大変だ。
基本的に >174 に賛成。 パーツとして使うものなんだからできるだけ無駄は排しておきたいというのはおかしなニーズだとは思わない。 全体に寄与するかどうかは別だけど、寄与しないから無駄だと思ってる奴は馬鹿が無駄に工数投入してるって せせら笑っとけばいいだけなんじゃないの? 他人が無駄な工数を投入しているのが許せないとかそんな潔癖症でもないだろ、おまいら。 個人的には標準が要求する Allocator とか Sequence の要件を満たして実装できるのかが興味あるな。
全体の速度測ってから考えろ。 動的に複数回の変更しなければ、どんなメモリ確保の仕方でも大差つかない。 vectorを多めにとって置きresizeつかえ。 拡張する自体になったとしても全体の影響は少ない。 初期化コストとかアホが考えること。
メモリ初期化よりも、広大なメモリ空間確保すること自体が速度落とすぞ。 現代のPCはマルチタスクだ。一つのソフトが大きくメモリ占有したら OS全体で仮想メモリの使用が増えて遅くなる。 低メモリを重視して、多くてもメモリ50Mくらいですむようにアルゴリズム考え直せ。
つーかCPUの2次、3次キャッシュも効かないような広大なメモリ空間をアクセスする ソフトを作ると大幅に速度が落ちるぞ Photoshopなどはこれを回避するために特別な方法を使っている
シーケンシャルなアクセスはキャッシュにヒットする確率が高いけど やたらランダムにアクセスするアルゴリズムは対象サイズが大きくなると駄目だろうなあ
C++の活躍の場はPCだけじゃないってこと時々でいいから思い出してあげてください コンシューマ機のロード処理とかで極力余分なコストを省きたいことがあるけど 大抵はboost::scoped_array/boost::shared_arrayで問題ないなあ サイズが変わるのはロードしなおすときくらいだからreset()で十分足りるし
STLの例えばlist なんかを静的メンバにする場合、初期化する場合はどうやってやるのでしょうか 例えば int型だったら int Class::member = 0 とかやればいいですよね でも listの場合だと list<Class1> Class::member = ? となってできません list じゃなくても普通のClass も同じことですが
>>189 コンストラクタがあるんで初期化子がなければデフォルト初期化でちゃんと空の list が
用意される。引数付きで初期化したければ ...::member(...); とすればいい。
今日日コンシューマ機でもそんなにコスト高くねえよ。 毎フレいじるならともかく。
俺毎フレでSTLのコンストラクタ走らせてた…。 pool使ったアロケータをtemplate型に与えてたから速度にそんなに影響しないと思ってたけど結構きつかったよ。 ごめんねコンピューター。
最適化の弱いライブラリだとTがPOD型でもstd::uninitialized_fillが for文で一要素ずつ0埋めしてたりするからね。要注意ですよ。
標準のallocatorクラスは組み込みのnewと比べて大差ないからね^^ それでもアプリケーションレベルのプログラマんは十分な性能だと思うけど
STLportのstd::allocatorは内部で固定サイズのメモリプール使ってる
windowsでphpをC++に変換するか、 C++でphpの関数がつかえるヘッダファイルなどありますか。
phpがもっとも使える、優れていると思うのでプログラムをphpに統一したいです。
php使えばいいじゃん C++関係ないじゃん
phpは遅いのと、guiやグラフィックができないです。 ネイティブのEXEを作りたいです。
phpは遅いのと、guiやグラフィックができなくて、ネイティブのEXEも作れないのに、 どこが使える、優れているんだら?
>>200 C言語系列は知ってて損はないよ。お手軽にC#っててもあるぞー。
C#はちょっと・・・ 5年後には確実に役に立たない知識になるし
C++の5年後か・・・ 0xは完成しているんだろうか
5年後にはC#も8.0ぐらいになってるのかな
>>203 MS製の言語なんてそんなもんだよ
それか名前は同じでも中身は全く別物になってたりする
MSしかサポートしていない言語だから 飽きたらサポートされなくなる可能性高いよね J++も消えたし。J DirectとかWFCとか覚えた人はご愁傷様って感じ。
>>201 言語の性能・使いやすさとコンパイラ・翻訳は別。
それにphpがDirectX、winAPIを扱えるように拡張することも開発者がやろうとしたらできる事。
>>207 貴様はMonoとvalaを侮辱したな…
.netはプラットフォームにかなりべったりだけど、
C#自体はかなりイカした言語だと思うぜ。
そうね、Javaよか幾分マシなくらいな
でもこれってすごい事よ。
C++でメモリ周りに辟易したらC#良いよ。インターフェース思考のものがザクザク作れる。 まー、最近だとC++でもスマートポインタ入っていくらかマシになったけど。
>>198 phpに統一したい、C++を使いたいってことでいいのかな。
なら、phpのモジュールをC++で書けばおk。
xに何が入るかを考えるなんて思考停止の極み。36進数または62進数であるとは考えないのか
>>213 n進数としてn→∞ならあらゆる自然数を10-1で表現できるもんなぁ…。
>>208 PHP は処理系が一つしか無い訳だから、それは当て嵌まらない。
現実を無視して、過度な一般化をしても意味は無い。
設計の相談です。 現在、次の法則でコンテナが増えていってます。 std::vector<AClass> aList; std::vector<BClass> bList; std::vector<CClass> cList; exec1(){ for_each(aList.begin(),aList.end(),std::mem_fun_ref(&AClass::exec1)); for_each(bList.begin(),bList.end(),std::mem_fun_ref(&BClass::exec1)); for_each(cList.begin(),cList.end(),std::mem_fun_ref(&CClass::exec1)); } exec2(){ for_each(aList.begin(),aList.end(),std::mem_fun_ref(&AClass::exec2)); for_each(bList.begin(),bList.end(),std::mem_fun_ref(&BClass::exec2)); for_each(cList.begin(),cList.end(),std::mem_fun_ref(&CClass::exec2)); } 10個20個と、今後もこの法則で増えていきそうなので、 コンテナ自体をコンテナに詰め込んでまとめてexe1(),exe2()などを呼ぼうかと 思ったんですが、よく考えると、型が違うのでコンテナに入れられないですよね。 すっきりする方法ってありますでしょうか?
class Base{ public: virtual ~Base(){} virtual void exec() = 0; }; class AClass : public Base { public: virtual void exec() { } }; std::vector<Base*> aList; これでは?
わざわざコードまで書いていただいて有難うございます! 実は、newを使う実装に抵抗があってずっと避けていたのですが、 確かに構造的にはスッキリしそうですね。 これを機に、スマートポインタを使って ご提案いただいた方法で挑戦してみます! 有難うございました。
デフォルト引数でポインターではないクラスを初期化する方法ないんですか?
>>219 どのレベルで言ってるか良くわからないが、初歩であれば、
CHoge Hoge(Arges);
って言う感じじゃね?コンストラクタもそれように書く!
>>219 ありますよ。
class C { public: C(int v = 0) {} };
えっ、違いますよ。 void function (Class Cデフォルト(引数)){} のようなことですよ?
void function (int a=3 ,Class C(デフォルト引数)){} 訂正
>>222-223 △ デフォルト引数でポインターではないクラスを初期化
○ ポインターではないクラス型の引数にデフォルト実引数を指定
ってことかな?
void function (int a=3 ,class C = C(...)){}
>>224 ありがとうございます。
たぶんそれですが
初期化してからコピーで、厳密には初期化じゃないですよね。
>>225 コピーじゃないよ。 operator = () が呼び出されたりはしない。
えーーっ、じゃあ、イニシャライザーなんて必要なくね?
なんでそうなるかな?
>>226 コピーされるかどうかの話ならコピーコンストラクタが使われるかどうかを確認するべきでしょう。
引数で実体を渡すとなると、一度呼び出し元の関数上でオブジェクトを構築してから、コピコンで呼び出し先の関数に渡すんじゃない? デフォルト引数は呼び出し元の引数の記述を省略できるだけで、動作に変化はないんじゃない? 規格は確認してないけど
コピーされたくない場合は参照で渡せばよかとよ
class C = C(...) こう書いたとき、operator =() は呼ばれず、代わりにコピーコンストラクタが呼ばれる可能性がある その上で、コピーコンストラクタを呼び出す処理を省略する実装が許されている、だっけ? ちなみに参照のときってこう書けばいいの? void function (int a=3 ,class &C = C(...)){}
とりあえず、コピーコンストラクタの呼び出しとコピー代入演算子の呼び出しを 同じ「コピー」と呼ぶのはやめよう。ちなみにゆとりちゃんの勤めている会社はポプー。 C c; C a( c ); // コピーコンストラクタの explicite な呼び出し C a = c; // コピーコンストラクタの implicite な呼び出し a = c; // コピー代入演算子の呼び出し void f( C x = C() ); f( c ); // x はコピーコンストラクタの explicite な呼び出しで生成 f() // x は引数なしのコンストラクタの呼び出しで生成 見た目が同じでも意味が違うのであった。
class C(...) として扱って良いだったはず
あ、ごめん。 f( c ); // x はコピーコンストラクタの implicit な呼び出しで生成 の間違いですた^^ あと、implicit, explicit でつづりも間違い^^;;;;;
236 :
220 :2011/02/28(月) 18:31:02.80
関数かいな、マジボケしてた。。。Orz
>>234 ありがとう。
MyClass foo = MyClass();
と書いたとき、下記のいずれで実装してもよい、ですね。
・コンストラクタ + 代入演算子
・コピーコンストラクタ
だめに決まってんだろ。
次いってみよう
金ダライの衝撃は80kgほどである。
242 :
デフォルトの名無しさん :2011/02/28(月) 22:38:27.36
C99も10年以上経っているのに いつまでもコンパイラが枯れないね
C++0xは何年やってるんだっけ?
現行はC++03
現行はね。
7,8年前?に読んだC++入門本なんですが、なんだったかのか思い出せません。 少なくとも2分冊、恐らく3分冊で、1冊が5cmほどで、カバーを外すと1冊が緑一色、1冊が青一色。 多分洋書の和訳。 STLについても書いてあったはず。 なんかうさぎと亀のシミュレーションとか、アキュムレータマシン(か、レジスタマシン)の仮想マシンとか書いてあったような。 すっごい面白かったはずなんですが、誰か書名を教えてくれませんか?
ひとつの関数を作るためだけに使い捨てのクラスを作ることってありますか? Cで書くのと同じように関数内にゴリ押しで詰め込んだほうがいいですか?
テンプレート使ってるとそんなヘルパクラスは山ほどできるよ。
>>247 関数は作る。
クラスを作るかどうかは状況による。
使い捨てのクラスを作ることはない。
std::absがテンプレートだと思ってint64_tを食わせたときの絶望感はひどい。。。@VC10EE
と、思ったら俺の勘違いだった。おかしなことかいてすまねー。
252 :
デフォルトの名無しさん :2011/03/10(木) 19:19:48.69
質問です。
http://ideone.com/ZdhCm 関数に渡す引数を柔軟にしたく、
コンストラクタの暗黙変換を活用するコードを書いたのですが、
テンプレート引数の型が派生関係にある型では
マッチしてくれないことが分かり困っています。
こういった場合の一般的な解決方法がありましたら教えてほしいです。
template<class T> void Func(T const & obj);
254 :
252 :2011/03/10(木) 19:56:15.58
>>253 ありがとうございます。が大変申し訳ないです説明不足でした。
引数を柔軟にというのは、複数の型から変換できるという意味合いです。
http://ideone.com/BxMks ・・ってああああ!分かってきました!
曖昧にしておきたいテンプレート引数に当たる部分は一旦Tで受けておいて、
更にそのTを関数オーバーロードを利用して具体的な型に近づくように
振り分けてあげれば良さそうですね!
・・ただこれって結構深いテンプレート深度だと書くの大変そうですよね。
これから試してみようと思いますが、このやり方しか方法は無いんでしょうか?
Wrapperにインターフェイスを定義したベースクラスをくっつけてやればいいんじゃないの? class BaseWrapper{ } template <class T> struct Wrapper : public BaseWrapper { }; struct Hoge { }; void Func(const BaseWrapper& arg) { } 的な。
256 :
252 :2011/03/10(木) 21:04:01.65
>>255 ありがとうございます。ただ、意図しているところがちょっと分かりませんでした。
全ては私の説明が下手なせいで・・ごめんなさい。
一応
>>254 での方法で振り分けができたのですが、
なんだか多分スマートではない感じになりました・・。
http://ideone.com/svWr7 これで進めてみますが、もっと良い感じの
コードがありましたら教えてほしいと思います。
一旦これにて、皆さんどうもありがとうございました。
>>256 ImplicitCasted Convert(int);
ImplicitCasted Convert(Hoge const &);
ImplicitCasted Convert(Wrapper<Hoge> const &);
template <class T> ImplicitCasted Convert(Wrapper< HogeHoge<T> > const &);
template <class T> void Func(T const & obj) {
ImplicitCasted const & ic = Convert(obj);
}
キャストなんてどうしようもない時だけにするものだから
キャストしまくる前提のクラス設計なんて最初から見直したほうがいい、と言いたいけど…
まあ、どうしてもやりたいなら、俺ならこうする
258 :
デフォルトの名無しさん :2011/03/12(土) 07:58:40.12
問を1つ。 継承なしに関数のオーバーライドって可能ですか? つまり「 : public ClassName」を使わないで。
つまり: protected ClassNameならいいと 無理じゃね
260 :
デフォルトの名無しさん :2011/03/12(土) 09:15:36.17
いや、:〇〇を使わずにw さらに、サブクラスにスーパークラスのヘッダーファイルをインクルードも禁止なのです
継承なしで似たことができたとしてもそれはオーバーライドとは呼ばないので
262 :
デフォルトの名無しさん :2011/03/12(土) 11:40:51.21
たまたま見つけてしまったから、既出の技術か確かめたかったのです。 身近に相談出来るプログラマーなんていないからw
同じようなことは出来るだろうけどオーバーライドとは呼ばないし移植性もなくなるだろうな
静的多態はオブジェクトの型に応じて呼び出し関数を上書きはするけど オーバーライドの機能をすべて実現することはできないしね。 あと、C++のときはサブクラス、スーパークラスと呼ぶのはやめようぜ。 なんか肛門がぞくぞくする。
>>262 その見つけたコードを書いてみるといいよ。
意味わかんないけど、関数ポインタ使ってじゃないよな?
関数ポンタなら使ってます
関数ポインタ使った実装とオーバーライドを同一視するとか初心者かっての
COMみたいな実装ならそれを言語で自動的にやってくれるようにしたのが 仮想関数システムなわけだが。 継承関係の無いクラスの動的多態、ならFaith and Braveで記事があったと思う。
C++の仮想関数は関数解決に仮想関数テーブル使ってるから、単純な関数ポインタでは同じ実装はできなよ。
なよw
なよなよ
273 :
デフォルトの名無しさん :2011/03/13(日) 15:22:37.69
情報サンキュー。 もう少し正確な裏付け取るため別をあたってみたいと思います。 コード公開できるようになれば報告しに来ます!(`・ω・´) 因みに267は俺の発言ではないのです。そして関数ポインタなんて使ってませんw
std::dequeは末尾の削除以外の要素追加/削除を行ったらiteratorが無効になるとありますが、 dereferenceした直接の要素へのポインタや参照もstd::vectorみたいに無効になるんでしょうか? 推測ですが、iteratorが無効になるのはランダムアクセスに使っているindexの配列の再構築が行われるからであって 要素そのもののメモリ空間の操作はないと思うのですが、実際はどうなんでしょう。
>>274 「dequeはイテレータが無効になってもポインタや参照は無効にならない」
とEffectiveSTLに書いてあるけど。
つーわけで、Eff STLは持っとけ。
substr関数を使わずにポインタを弄るだけで文字列 "12345"を"1234"または"2345"に変える方法ってあるの?
\0使え
void func(char * buf, char const * str, unsigned len, unsigned offset) { sprintf(buf, "%*.*s", len, len, str + offset); } char buf[100]; func(buf, "12345", 4, 0); puts(buf); func(buf, "12345", 4, 1); put(buf);
> unsigned len, unsigned offset 順番がキモい
281 :
279 :2011/03/16(水) 04:23:51.03
すまん、寝惚けてたんだと思う。
>>275 vectorみたいに再配置が起きないの?
dequeってメモリ上連続していることが保証されてるんじゃないっけ。
ごめん勘違いだった。
>>282 連続してねえよ
チャンク単位でバラバラ
operator[]が使えるってだけの話
ですね。ごめんなさい。 []が定数時間でアクセス可能というところで、データ自体が連続領域なのかと勘違いしてた。
即座に勘違いだったと撤回してるのに13時間後にドヤ顔で突っ込む男の人って・・・
ヘッダに、 static void Func() { static char buffer[1024]; } と書いて複数のcppからインクルードすると、 staticなので内部リンケージということから考えて、 関数が複数コピーされて、 buffer[1024];は静的領域に複数確保されてしまいますか?
はい。
C++って何でも出来るらしいけど何にも作れない。。。 例えばPythonとかだったらFTP鯖とかftplibモジュールとか使えばすぐ作れたりするけどC++だと全然どうやって作っていけば良いのか分からん。 入門書読み終えて立ち尽くしてる状態だわ
C++だけじゃ無理だな OSの力を借りないと
ライブラリの力を借りてみよう 特にネットワークは環境依存プログラミングになりがちだから、 とりあえずクロスプラットフォームのライブラリさがすのベターでは
>>291-292 どうもありがとう。
言語の勉強するんならとりあえず何か作れと良く言われるからDXライブラリとか外部のライブラリ使って何か作ってみる
>>290 > C++って何でも出来るらしいけど何にも作れない。。。
真理。
>>293 > DXライブラリ
Qtライブラリがおすすめな気がするけど。
DXもまあ勉強するならいいのかもしれないが、クロスプラットフォームじゃないしねぇ。
環境依存が強すぎる気がする。
>> C++って何でも出来るらしいけど何にも作れない。。。 >真理。 足りない言葉がある。 C++って普通の人間なら何でも出来るらしいけど、馬鹿には何にも作れない。。。
C++は専門職のための仕事道具だって禿も言ってるしな。
専門職じゃなくても、あれこれ要求あげていくと、結局C++になったり 似たような言語ありそうで、ないんだよな D言語には、代替として凄く期待していたんだけど、いつまでも「乞うご期待」だし
>>298 > 似たような言語ありそうで、ないんだよな
そうそう。
C++は結局逃れられないのだ。
>>290 通信の勉強をして、次に、FTPのRFCをよんで、仕組みを理解したら徐々に作っていく
既存のライブラリで済ませるんなら、そっち方面をあさるのもいい
でも自前で作るのって相応の理由がないと、大抵損だよ。
const_cast の存在理由が分からないです。 const っていうのは、理由があって書き換えられないようにするために付けるものだと思いますが、 こんなキャストがあるおかげで、結局はconstを外せてしまい、constの意味がなくなってしまうのでは。 それにconstを外すなんて、どう考えてもバグの元だと思うのですが。 「constは絶対に外せない」とした方が良くないですか?
>>301 constメンバ関数と非constメンバ関数を一つにまとめる時とか
const を付ける為だけに使えば無問題
>301 基本的には使わないと思っておけばいいよ。 良くあるケースは提供されたライブラリに、引数を変更しないのに const ついてない関数があって ライブラリ側のソースが直せないけど渡したいケースとか。 理想としては const_cast なくてもいいはずだけど現実的には難しいって感じ。 あるいはライブラリ外部に対しては const として公開しておいて内部では const 外して処理するとか いう使い方もあるみたい。
>>303 付けるほうは static_cast にしてください。
そんなのが const_cast の検索にひっかかるとウザイ。
static_castが万能なのはどうにかならなかったのかな 検索に引っかかりすぎてウザイ
非const→constはキャストいらないだろ
309 :
デフォルトの名無しさん :2011/03/19(土) 16:00:46.92
禿本には「キャストが必要になるのは悪い兆候なので注意せよ」と書いてあるしな
T const *pc = p; pc->f(); とするか const_cast<T const*>(p)->f() とするかみたいな話では。 常に前者で書くなら const_cast は要らないかもね
最初から
>>302 が書いてくれてるけど
iterator begin() {...}
const_iterator begin() const {
return const_cast<T*>(this)->begin();
}
みたいな時に使う感じ
>>307 constつけるのにも毎度毎度const_cast書いてたの?
「危険なことは言語仕様でできないようにしてほしい」と思うなら 単純にJavaみたいな思想の言語を使えばいいだけなんだよ。 言語ごとにパラダイムが違うんだから適材適所でいいんだよ。 C++もJavaと一緒にされちゃったら存在価値なくなっちゃう。
>>310 前者じゃなくても static_cast でいいんだってば。
cv修飾を変えるだけの用途であっても static_cast を使うべき と言ってるのかな 論拠はなんなのだろう
>>315 const_cast は危険な操作をそうとわかるように表記するために作られた。
しかし const の付加はそのような危険な操作ではない。
const の付加に const_cast を使うと、 const_cast をキーワードとして
危険な操作を探した場合にノイズとして引っかかる。
安全な操作であるぶん数も多くなり、本来の目的であった危険な操作を
見つけることを難しくしてしまう。
constを加えるならconst_castを使わず常に310の前者のように書け というならOK でもそれなら static_cast 関係無くね?
>>317 const を加えただけのポインタや参照に名前を付けたくないとき、 static_cast で済ませることがある。
>>311 とは逆に↓とか。
X const& f() const {...}
X& f() { return const_cast<X&>(static_cast<T const&>(*this)->f()); }
細かいことだが
実際の定義はconstでやる方(
>>318 )が正解
逆は良くない
なぜならconst_cast<T*>(this)の時点でconstなメンバが変更される余地を残してしまうから
EffectiveC++より
>>318 それ const_cast でいいよね
だめだよ
static_cast でcv修飾を加えることは出来るけど、それなら const_cast の方が 安全で意味を直接に表現出来る。 static_cast でcv修飾を除くことは出来ないから、その場合 const_cast を使うしかない。
>>320 static_cast より const_cast が安全だ、あるいは逆に static_cast のほうが危険だという理由は何?
意図しない const/volatile の除去が発生する可能性のある const_cast のほうが明らかに危険じゃないか?
すまんが釣りにしか見えんのよ
const_cast< T const * & >( p )->f(); // やった!一時オブジェクトを作らなくてすんだぞ^^
>>326 >>323 あと、 stackoverflow のリンク先は const_cast との比較ではないから関係ない。
>>326 >static_cast は C++ の道具の中で最も危険なツールの1つであり、
ここ誤植じゃないでしょうか。
reinterpret_castの項目で、static_castの危険性を(より危険なreinterpret_castを引き合いに出して)説明してるのに違和感が・・・
>どちらの形式でも正常に動作するという場合でも、私はやはり reinterpet_cast の使用を推奨します
( ´゚д゚`)エー
317にもあるけどconst_castを使わず暗黙の変換を使え、なら分かるんだが static_cast と const_cast なら static_cast を使うべき、という主張なのだろうか 目うんこと鼻うんこに感じるんだけど
int* p = NULL; if( p ) とやるのと if( p != NULL ) とやるのはどっちがいいですか?
俺は、static_cast と reinterpret_castだったら後者のほうが怖いけどね。
>>332 せめてC++だったらNULLではなくて0を使おうよー
C++0xならnullptrを
0はキモイからいやだ
バイナリ値をもとに式を組みかつ挙動を把握し切れてない人にとってはstatic_castが厭らしい問題を引き起こす厄介者に思えるのかもしれん。
遅ればせながら… struct A : B, C {... void C::f() { static_cast<A const*>(this)->f(); // 未定義動作 } 間違えば static_cast でも未定義動作なのは同じでしょう。 「俺はそんな間違いをする筈無い」ということなんだろうけど それは const_cast も同じ。 static_cast も const_cast も危険で注意すべき箇所という事に 違いは無いと思う。
>>329-330 だいぶ前にもその記事出たんだけど、
記事自体が古い上に、Effective C++のメイヤーや、Exceptional C++のサッターとかから
「何いってんだ、クソが」みたいな投稿があって、フォーラムだかコメントだかで論争になり、
結論として「ごめんよ、ビット列をそのまま解釈するreinterpret_castの方がやっぱキケン」
って次のコラムで論争の内容をまとめた上で謝ってたように思う。
C++ではCのNULL( void*(0) )と同じ動作しないしね。 詳しくはEffective C++に載ってたはず。
>>332 元の意図である「p がヌルじゃなかったら」に近い後者のほうが読みやすい気がする。
でも NULL を使うためにヘッダのインクルードが必要になるのはダルイので、 0 か、
可能なら nullptr を使うのがいい。
>>340 static_cast も const_cast も危険な操作として後から探すと思うんだけど
見つかった static_cast なり const_cast が const を足すだけだった
と分かって紛らわしいということだよね?
static_cast を探した時に見つかるのと const_cast で見つかるのと
そんなに違うのかい?
>>317 >>331 と
>>342 にあったリンク先にも書いてあるけど
暗黙の変換で済むならそれに越した事は無いと思うんだよね。
342のリンク先では、どうしても使うなら static_cast の方が
まだましとあるけど、
>>337 にあるように、一方のキャストの
危険度が有意に高いということは無いと俺は思ってる。
const を付けるのに {static/const}_cast 使うとかプギャー
というなら完全胴衣なんだが
>>343-344 たいして違わないけど全く違わないわけでもない。
暗黙変換で済ませるのがベストなのはみんなわかってるだろう。
new演算子はスレッドセーフですか?
>>347 ありがとうございます。
仮にスレッドセーフではないと仮定するならば、
複数のスレッドでnewが入る場合は、
newが行われるスレッドが動いている間、
必ずすべてのnewで排他制御が必要になるということですか?
349 :
デフォルトの名無しさん :2011/03/20(日) 21:54:48.75
>>349 なるほど・・・
すべてのnewで排他制御の他にスレッドセーフへのアプローチ方法はありますか?
スレッドセーフなAllocator渡すのが普通じゃないかな
自分で ::operator new をそのように実装するとか
ありがとうございます。
>>351 やはりそのあたりが現実的でしょうか
>>352 仮にoperator new をしてもすべてのnewをのっとれるわけではないですよね?
VC++だとスレッドセーフ版とそうじゃないのを選択できるよね GCCはよく知らん
>>350 スレッドが動く環境のコンパイラなら new なり malloc なりの下位層で対応済みなことがあるから、
まずは環境についてのドキュメントを確認したほうがいいんじゃないか?
357 :
デフォルトの名無しさん :2011/03/21(月) 22:01:14.81
文字列に数字(2桁以上を含む)とアルファベットが混ざっていて、 "ab100cd33e" => a b 100 c d 33 e という感じに、数字はまとめて配列か、tupleに入れてくれるようなライブラリはないでしょうか。 また、近い使い方が出来るものも無いでしょうか? 現状、istringstreamのget()メソッドで一文字ずつ取り出して自力で解析するコードが見難くて困っています。
#include <algorithm> #include <iostream> #include <boost/xpressive/xpressive.hpp> int main() { using boost::xpressive::digit; using boost::xpressive::alpha; std::string input("ab100cd33e"); boost::xpressive::sregex token = +digit | alpha; boost::xpressive::sregex_token_iterator begin(input.begin(), input.end(), token); boost::xpressive::sregex_token_iterator end; std::vector<std::string> array(begin, end); std::ostream_iterator<std::string> output(std::cout, "\n"); std::copy(array.begin(), array.end(), output); } こんなんでどうよ
おっと…上のほうに #include <string> #include <vector> #include <iterator> を足しといて
boost::tokenizerで別途連結する文字集合に0, ..., 9を入れればできるよ。
361 :
357 :2011/03/22(火) 00:40:24.42
>>358 カッコ良過ぎる・・・
ありがとうございます。
こういうC++的な書き方は非常に参考になります。
>>360 boost::tokenizerで出来ないか丁度検討してました。
可能だと分かり、助かります。ありがとうございます。
class A { int i; class B { B(){ //ここでA::iにアクセスする方法ありますか? }; } A(){ B b; }; }; 上にような構造のクラス作る時、外側のクラスの変数に簡素にアクセスする方法があれば教えてください やはりBのコンストラクタあたりでiを渡さないといけませんか? わかりにくかったらすいません
AのインスタンスをBに渡せばいいだけの話。
最低でも A::A(){ B b(this); } のように渡さないといけないということでしょうか 言語的に外側のクラスから引っ張ってくるようなことはできないのでしょうか
>364 少しは自分の脳みそで考えてみろ。 A::B というクラスは A とは独立して存在するんだが、どの A オブジェクトの i をアクセスするというんだ。
うつ病で海馬がやせているんです…ごめんなさい;ω;
うつ病で海馬がやせているんです…ごめんなさい;ω;
クラスの中にクラス入れても独立させても名前空間の違いしかないということなのですね 何かアクセスする方法ができるのだと思っていました
i を性的変数にすればアクセスできるよ。
桁指定の0詰めをしたいけど cout << setw(4) << setfill('0'); cout << 0 << endl; cout << 0 << endl; とかくと"0000", "0" となります。 1回の設定で全部のcoutに桁指定0詰めをさせる方法はありませんか? cout << setw(4) << setfill('0') << 0 << endl; cout << setw(4) << setfill('0') << 0 << endl; と書くとオーバーヘッドがありそうで…。
>>370 素人め!そんな軟弱なCPU使ってるのかよ。と突っかかってみる。
まー、それくらいのオーバーヘッドはたいしたこと無い。
それより、その設定を残してプロジェクトで混乱起こすよりましじゃね?
>>370 std::printfを使えばよい。cout使う奴はあほ
>>370 フラグでORを取っておいてsetfを使うといいのでは?
全部のcoutという表現は正しくない
一度出力を終えるとリセットされてしまうフラグとそうでないフラグがあるだけの話
スタックに作ったオブジェクトをvectorに入れていくのと ヒープに作ったオブジェクトをvectorに入れていくので 前者の方が手間がかからないと思うのですが 後者のメリットは何ですか。
お前にC++はむり
もったいぶらずに教えてくださいよ
>>376 スタックに確保するアロケーターのvectorと
フリーストアに確保するアロケーターのvectorの比較だろ。
前者はすぐにメモリが解放されるので使い物にならない。
string s("hoge");
vec.push_back(s);
string*p = new stirng("hoge");
vec.push_back(p);
>>374 がvectorにアロケータが渡せるなんて知らないだろうからこっちの意味だろう。
後者は犯罪。
>>379 後者がポインタの vector なら、コピーできない(コピーのコストが高すぎる)オブジェクトにも対応できる。
そうでもなければ使う必要が無い。
>>382 わかりました!!
ありがとうございます"!!
385 :
デフォルトの名無しさん :2011/03/27(日) 03:30:42.33
>>360 boost::tokenizer で数字の連結なんて出来るんですか?
boost::tokenizer で数字以外の全ての文字を区切り文字に指定する方法しか思いつかないですが、
そんな方法が最善とは思えません。どうするんでしょうか?
rewa
コンパイル時に整数の桁数を計算する方法教えてください
#include <iostream> template <int N, int M = 0> struct hoge { static const int keta = hoge<N/10, M + 1>::keta; }; template <int M> struct hoge<0, M> { static const int keta = M; }; int main() { std::cout << hoge<111>::keta << std::endl; } 自信ないけど
ありがとう
>>387 template<int N> struct keta { static int const value = keta<N / 10>::value + 1; };
template<> struct keta<0> { static int const value = 1; };
template<> struct keta<1> : keta<0> {};
template<> struct keta<2> : keta<0> {};
template<> struct keta<3> : keta<0> {};
template<> struct keta<4> : keta<0> {};
template<> struct keta<5> : keta<0> {};
template<> struct keta<6> : keta<0> {};
template<> struct keta<7> : keta<0> {};
template<> struct keta<8> : keta<0> {};
template<> struct keta<9> : keta<0> {};
#include "boost/static_assert.hpp"
BOOST_STATIC_ASSERT(keta<0>::value == 1);
BOOST_STATIC_ASSERT(keta<9>::value == 1);
BOOST_STATIC_ASSERT(keta<10>::value == 2);
BOOST_STATIC_ASSERT(keta<99>::value == 2);
BOOST_STATIC_ASSERT(keta<1000>::value == 4);
BOOST_STATIC_ASSERT(keta<9999>::value == 4);
BOOST_STATIC_ASSERT(keta<10000000>::value == 8);
BOOST_STATIC_ASSERT(keta<99999999>::value == 8);
>>389 BOOST_STATIC_ASSERT(hoge<0>::keta == 1);
:12: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
>>387 #include "boost/mpl/if.hpp"
#include "boost/mpl/int.hpp"
template<int N> struct keta : boost::mpl::int_<1 + boost::mpl::if_c<(N < 10), boost::mpl::int_<0>, keta<N / 10> >::type::value > {};
shared_ptrとunique_ptrの使い分けについて 木構造でshared_ptrを使おうと思っていたのですが、親へのポインタを持つと循環参照の問題が出てきます 回避策として親へのポインタを生ポで持たせようと思ったのですが、それではshared_ptr使う意味がない そこでunique_ptrで寿命を管理し、生ポで参照させようとしたのですが、どうも不格好な気がします 生ポを出すと知らぬ間にdeleteされるかもしれない、でもそれはshared_ptrでもできないわけではない こういう場合、コストを払ってでも、所有者が複数いることを明示するためにshared_ptrを使うべきでしょうか?
親は子をunique_ptrで持ち、子は親の参照を持つでいいやん
weak_ptrは?
weak_ptrは今回のケースではどんぴしゃですね
ただ循環参照の問題はきっかけではありますが本質ではなく、
端的に言うと、スマートポインタ使用時に生ポを出すのはありなのかという疑問です
>>395 が一番スマートなのでしょうか
なぜか全く思いつきませんでした
shared_ptr<int> obj1::get() {
return ptr; // shared_ptrオブジェクトを返す コスト大
} // 一時的に使用するために呼び出す場合でもshared_ptrで返すべきなのだろうか(一時的に所有すると考えるべき?)
const int * obj2::get() {
return ptr.get(); // 生ポを返す
} // 生ポを出すのは不格好な気がする
const int * obj3::get() { // unique_ptr<int> ptr;
return ptr.get(); // 生ポをむき出しにするのであれば、unique_ptrでいいのでは
} // もちろんshared_ptrでなければいけないケースもあるだろうけど
>>397 基本的にはナシだけど使うときは使うかな
でもCとの連絡とモニカとしての利用以外で使うことはないな
>>397 の例だと
- shared_ptr<int>を返す
- const shared_ptr<int> &を返す
- (目的にあうなら)intを返す
のどれかがいいんじゃないかな
木については
- 子→親が必要ない場合は親→子だけをunique_ptrで管理
- いるならshared_ptrとweak_ptrで管理
- 平衡くさい2分木ならvector<T>(かvector<unique_ptr<T>>)で添字管理するのが楽なこともある(根は1で、左 = 親 * 2、右 = 親 * 2 + 1)
- 子が親の(C++の)参照を持つとノード削除したとき困ると思う
みたいな感じ
デフォルトの引数って使いますか? Googleスタイルだと禁止されてるんですけど
使いたければ使えば チームの意向があるならそれに従えばよろし
>>399 使わない
使う上で注意しなきゃならないこともある割りにはメリットが少ないし
C#みたいに引数指定で関数呼び出せるなら便利に使えるんだろうけどね…
質問です。 バイナリデータをファイルから読み込んで、メモリー上に格納する時、今までは std::vector<byte> を使っていました。 ただ、よく考えたら std::vector<byte> buffer(size); fread(fp, 1, size, &buffer[0]); とやると、bufferの初期化時に全て0初期化されますよね。 普段は気にならないのですが、大きなデータを読み込む時にはもったいない気がします。 この初期化を行わない、バイナリデータを格納するのにふさわしい代替品は無いでしょうか?
stringやnewでいいだろ。 それより初期化よりもロードが圧倒的にかかる。 細かいこと気にするな。
サイズ分かってるなら固定配列でいいじゃない
>>404 stringに、'\0'が入りうるバイナリ列を入れて良いものなのでしょうか?
newですと、解放責任の問題が厄介です。
shared_arrayが最も要件を満たすようですが、スレッドセーフなど機能が大きすぎる気がします。
それっぽいstd::arrayについて調べてみましたが、こちらは新たに型を作るもののようで、型を作りたいわけではないのでミスマッチでした。
stringは、charの配列。 wstringは、wchar_tの配列。 ばいなり格納可。
初期化にこだわる意味がわからん。 何度も生成するなら、消さずに使い回せ。 初期化に時間食うほど確保したら、ロードはものすごくかかるだろ。
10メガを100万回とかだったら、無視できないほどだろうが。アルゴリズムを見直せよ。 初期化が時間食うのは、他に何もしていないプログラムか、無駄なことをしているプログラム。
freadを使うところもオーバーヘッドかかるだろ。 unixはしらんがたとえばwinapiを直に呼べばロスは減る。
>>403 boostのscoped_arrayか0xのunique_ptr
質問です deque(変数名Aとします)を利用して以下の条件を満たせる配列を作りたいのです ・クラスのメンバー変数である ・A[0]~A[9]を作れる ・Aはint[2]を持つ ・Aにはいくつpushされるかわからない ・A[x]に対してpushを行うと、int[2]が追加される ・A[x]の中のint[2]の各要素に代入ができる こんな感じです A[0]={ [0,0,0] }→A[0].push_frontする→A[0]={ [1,1,1],[0,0,0] } →A[0].at?~[0] [0] = 2 →A[0]= { [2,1,1],[0,0,0] } deque<int[2]>やdeque<deque<int>>では上手くpushする方法がわからず作成できないのです もし「こうすれば上手くできる」、というのがありましたらそれでもかまいません
うまくpushができない例をあげたほうがいいと思う。 なんでかっていうと、pushできるから
dequeを選んだ理由もなんかあるんだろうけど、そこはさておき、 deque<deque<int> > か、deque<boost::array<int, 3> > でできると思うよ
deque<クラス>にすれば混乱は少なく出来るだろう。
deque<tuple<int,int,int>>a; a.push_front(make_tuple(1,2,3));
>>415 deque<int>にした場合 A[0].push_back()の時に渡す値がわからないのです。
A[0].push_back({0,0,0})とかint x[2]={0,0}A[0].push_back(x)だとエラーが出てしまって
>>416 なんかdequeが便利そうで・・・初心者なもので特に深い理由は
>>417 その発想はありませんでした
>>418 調べてみたらboostみたいですね。ちょっと試してみます
>>419 A[0].push_back(x)がエラーになるって書いてるけど、ほんとに?
再現コードを書いてくれないのも初心者だからですか?
deque<deque<int> > A;
A.push_back(deque<int>());
A[0].push_back(3);
これはエラーになりますか?
>>421 コンパイルされたクラスの テンプレート のインスタンス化 'std::deque<_Ty>' の参照を確認してください
みたいなエラーが出ます
再現コードはこんな感じですね
Class Class
{
deque<int[2]> A[9]
};
void F(Class &Class){
int x[2]={0,0};
Class.A[0].push_back(x);
}
deque<deque<int> > A;
A.push_back(deque<int>());
A[0].push_back(3);
は上手くいきました
>>422 deque<int[2]>は無理だよ。
>>423 そうみたいですね
皆さんのおかげでうまくいきました。ありがとうございました!
class Parent { virtual ~Parent(void){} }; class Child : public Parent { void ~Child(void){} }; class Grandchild : public Child { void ~Grandchild(void){} }; Parent *p1 = new Grandchild; Child *p2 = new Grandchild; 上記のような構成の時、Childクラスのデストラクタにもvirtualを付けた方がいいのでしょうか? C++の解説サイトを回ると付けている方が多いのですが、付けずにp1やp2のように使った場合でも問題なくデストラクタが呼ばれたので、どうするべきか悩んでいます。 virtualを付けること、付けないことによる不利益などありましたら、教えていただけるとありがたいです。 なお、コンパイラはVisual Studio 2008を使用しています。
継承して使うつもりならつけた方がいいでしょ
>>425 親がvirtualなら子も自動的にvirtualになるから付けても付けなくても一緒
付ければ見た目にわかりやすいかもしれないが、いちいち冗長で、省略できるものは省略すればいいじゃんと思う人もいる
>>425 自分で理解して使う分にはいいと思うけど
仮想デストラクタでない=継承しないで欲しいの意で使う人がいるから
留意しておくといいかもしれない
関数f(int a,int b,int c)でn=0として f(++n, ++n, ++n)とf( n++,n++,n++) をやってみたらaから順に前者は3 3 3 後者は2 1 0だったようなあいまいな記憶があります。 なぜこうなるのか教えてください。
C++のスレにCの話を持ってくるバカ。
言語仕様の話に禿のFAQを持ってくるバカ ISO 14882はれよ >i = v[i++]; // the behavior is unspecified
「なぜこうなるのか」を訊かれてるのに言語仕様の話へすり替えるバカ
こうならねーよバカって言われてるのに気付かないバカ
未定義動作だが
>>430 にならないことが保障されてるとは知らなかった
>>438 対偶も分からずにプログラミングしてて大丈夫か?
>>425 で
Parent a;
Parent b = a;
などとするとC++0xではdeprecatedになりますが
現行のC++では問題ないのでコンパイラは警告してくれません
既存コード中にこのようなものがあるかを簡単に調べるにはどうすればいいですか?
コンパイラが警告だしてくれるようになるまで待つ
コピー不能にすりゃエラーが出るだろう
>>441 の場合はコピーコンストラクタprotectedにしとけばいいのかな??
>C++0xではdeprecated なんで?
explicitにしとけばいいだろう
うわっexplicitではだめです
448 :
デフォルトの名無しさん :2011/04/01(金) 20:57:33.56
一番いいコードを頼む
>>450 0xって、キモいな。
間違った進化を遂げているようにしか見えん。
ムーブコンストラクタを導入した辺りから怪しくなったよな 高速化のため仕方がないとは言え
時間がたてば心地よく見えてくるもんだろうか・・・
古い機能を削ぎ落としてくれれば心地良くなる
Boostのlambdaのあたりから既に文法に無理があったような
C++, 0xの気持ち悪さ、嫌いじゃないぜ
じきに慣れる
C++、いっかい文法をすっきりさせたらいいんじゃね。 ガベコレ無しのJavaやC#みたいな感じで。
互換性・・・。
互換無いならC++である必要ないんだって
462 :
デフォルトの名無しさん :2011/04/01(金) 23:17:47.42
>>459-460 その流れで、これまでいくつもの離反組が巣立っていったが
禿以上の台風の目になれた人はいまだにいないね
推奨しない古い機能は警告出すようにしてくれ
互換性なんていらんだろ 別にCとしてコンパイルするわけでもあるまい
じゃあDにでも行けよ
ちょっと相談に乗ってください。XMLライブラリ作ってるんです。 で、文字列を返す関数がたくさんあるんですけど戻り値の型で悩んでるんです。 必ず存在するのであれば無問題。 const wstring& getValue() const { return value; } 存在するか分からない場合はどうするのがよいでしょうか? 1.参照で返す。 const wstring& getAttribute(...) const { if(...) return value; else throw exception(); } 2.無理矢理参照で返す。 const wstring& getAttribute(...) const { return ... ? value : L""; } 3.stringのポインタで返す。 wstring* getAttribute(...) const { return ... ? value : nullptr; } 4.ポインタで返す。 wchar_t* getAttribute(...) const { return ... ? value.c_str() : nullptr; }
DOMの挙動に合わせるならgetAttributeは2でいいんじゃないの
bool hasAttribute(...)
>>466 boost::optional<wstring&>
っていうか参照返して大丈夫?
値で返さないと危ないし実装も制限されちゃうよ?
その前にネーミングがキモい | getValue
Camel記法disってんのか
キャメルとかどこ中出身よ? c++erなら小文字にハイフンだろ
>>467 おっしゃるとおりなのですが、return L""をやっていいものか少し不安です
>>469 メンバ変数を参照で返してはいけないみたいなことは最近よく聞く気がします
寿命による危険性は分かるのですが、ほかの理由はなんなのでしょうか?
static const wstring emptywstrng = L""; return emptywsring;
wstring getValueでいいよ
>>472 getValue…Haskell中
GetValue…Pascal中
get_value…C++中
異論は認める
Value・・・C#
Get_Value ハイブリッド
getValueはJavaのgetterのようで嫌だ
小指で入力するの苦手だからgetValueの方がいいなぁ
getval ... C
Cも小文字にアンダースコアだろ ただWin32APIはパスカルなんだよなw
標準ライブラリにみられる strpbrk とか atoi とかいうような短縮した関数名に倣ってみました
LPCTSTR lpszVal getval() C+WINAPIの凶悪さ
どこからつっこめばいいんだろう
>>466 その中ならば、1.の参照or例外がいいんじゃないか? 2は危険で警告出るし、3,4はnullptrの扱いが面倒だしバグを誘発しやすいし
例外がいやならboost::optionalで返す。
boost::optional<wstring> getAttribute(...) const { if(...) return value; else boost::none; }
こんな風に呼ぶ
if(auto x=a.getAttribute(....))
func(*x); //存在したときのみfuncする。
>>473 > 寿命による危険性は分かるのですが、ほかの理由はなんなのでしょうか?
469 にあるとおり、実装が制限されてしまうことが問題。
たとえば返したい文字列が既存のメンバ変数 a と b を繋げた a + b だとしても、
return a + b とはできず、 a + b を保持する ab のようなメンバ変数が必要になる、
など。
そのAttrノードの下に実は複数のTextノードがあってそれらの値をくっつけて返さなきゃいけないとかだな
どこかの翻訳単位にとある関数があるかどうかを調べる方法はありますか? 例えば、 void Hoge(); if(IsExitHoge()) { Hoge(); } のような
>>489 無ければリンク時にエラーになるから、そんな方法は不要であり存在しない。
>>490 まず発覚するのがリンカーなので無理ですよね
ありがとうございました
要素の重複を許さない高速なコンテナっていうとmapしかないでしょうか? 挿入する要素は100程度です
set は?
TR1で追加されたunordered_map(ハッシュ)、あとset/unordered_set 要素数100だったらmap/setの方が早いかもね
496 :
デフォルトの名無しさん :2011/04/03(日) 16:33:16.16
2つの無名名前空間内で同じ名前の構造体を定義すると、重複してるって怒られる。そういう仕様ですか? //file1.cpp namespace { struct A{}; }; // file2.cpp #include "file1.cpp namespace { struct A{}; }; // ビルド VC++2010EE error C2011: '`anonymous-namespace'::A' : 'struct' 型の再定義 でも、名前空間をBとCに分けると、当然ながらOKに。なんか納得出来ないんだけど。
>>496 .cpp をインクルードするな。
無名名前空間はコンパイル単位ごとにユニークなもの。ファイルごとじゃない。
無名名前空間って、他のファイルからは見えない〜って説明が多いし そうだと思ってたけど、本当は翻訳単位なのね。 勉強になりました、どうもセックスコ
他のファイルからは見えないと思っていたのにインクルードしたんだね
>>500 includeしたヘッダに無名名前空間しか無いとでも?
想像力が乏しい人だな
これが C++ スレか...
namespaceはC++じゃないか。「他のファイルから見えない」という 間違った説明を読んで ↓ ができると思ったんだろ。 file1.cpp: namespace {int x;} int &f1(){return x;} file2.cpp: #include "file1.cpp" namespace {int x;} int &f2(){return x;} 残念ながらC++は未だにCのプリプロセッサの糞仕様を引きずった言語
便乗で 無名の名前空間ってなんのためにあるんですか?
>>502 匿名名前空間なんだから個々は干渉し合わないと考えるのが普通なわけだがw
static とどう違うのっていう意味かな static だと内部結合だけど無名名前空間だと外部結合になるよ
意味のわからん説明するな。 内部リンケージと、絶対他から参照されない外部リンケージの 何が機能的に違うのかを説明してくれたまへ
お前ら規格ぐらい参照しろや
そのstaticはC++ではdeprecatedだから使うんじゃねえ! 素直に無名名前空間使え! と規格には書いてある 理由はいろいろあるけど気にするな
ファイルローカルな型を宣言するのに static は使えないから、無名名前空間が必要。
void test( char (&a)[ 8 ] ) {} の&ってどういう意味ですか?
void test( char a[ 8 ] ) {} とどう意味が違うんですか?
参照渡しは覚えるといろいろ捗るぞ
ふつうは、char *aだろ。
>>515 ポインタと参照の利点欠点の話じゃね?
個人的には参照で任意の長さの配列を取るテンプレート関数書けるから色々重宝してるな。
template<class T,int N>
void DoSomething(T (&Ary)[N]){
//DODODO
}
ちょっと踏み込めば行列演算もかけるよ。効率は書き方しだいだけど。
>>517 ふつうだけじゃ色々不都合があるんだよ。
>>515 引き数限定で、
char a // char
char & a // charの参照(通常使わない)
char * a // charへのポインタ
char a[8] // char *aと解釈される
char (& a)[8] // char[8]の参照
char (* a)[8] // char[8]へのポインタ
となる。
>>519 引数限定なのは↓だけでしょ。
> char a[8] // char *aと解釈される
C++関係ないな。
>>521 コードが公開されてるなら、それを移植。
コードが公開されて無いなら、想像して実装。
スクリプト上での便利機能を移植したいなら、結局関連する機能全部移植。
Cの上でやる以上、Cの文法からは逃げられないし、PHPライクにしたいならプリプロセッサ地獄におちるだろう。
>>501 includeしたヘッダの無名名前空間のみが見えなくなると思ったのか。おめでたいな。
変更することのない引数って、const参照にすることが多いと思うんだけど、 int とか charとかもしてる? それとも、集成型以上に限定してる?
const参照は変数がなくても渡せる利点がある。参照では無理だが。
528 :
526 :2011/04/04(月) 20:05:41.17
あ、constをつけるつけないではなくて、参照にするかどうかです。
クラスか否かだけだなー
intとかcharはコンパイラの最適化かかるから参照にしても速度的には意味ない
アドレスのコピーは4バイト位だから、概ねintと同じだし、プリミティブ型は理由が無ければ普通に宣言する。 かなー。
intとかcharは、参照やポインタ使うと速度的には少しだけ損だろ。
アドレスが4バイトって、お前、何世紀に生きてるんだよ
534 :
デフォルトの名無しさん :2011/04/04(月) 20:53:09.80
いつも威勢のいい兄さんでも 524 にはつっこめないのか・・・わかります
>>533 ふっふっふ、そこには抜け穴があって"位"って書いてあるじゃん。
別に8バイトでもいいのよ。概ねsizeof(int)位ってことで・・・。
すみません、ここで聞くことかどうか分かりませんが、 C/C++で「無線LANスポット」を一覧取得出来るようなネットワークプログラミング向けのライブラリ等ありませんでしょうか。
>>535 アホか
アドレスのサイズはsizeof(void*)
539 :
526 :2011/04/04(月) 21:15:49.19
どもでした。やっぱ何でも参照にするのはいまいちですよね。 たまに統一感があるからという理由でinはどの型でもconst参照、outはポインタにって現場があるので聞いてみました。
すみません、ここで聞くことかどうか分かりませんが、 C/C++で「Gスポット」の場所を取得出来るようなライブラリ等ありませんでしょうか。
541 :
536 :2011/04/04(月) 21:19:18.03
>>538 ご回答どうもありがとうございます。
探してまいります。
542 :
デフォルトの名無しさん :2011/04/04(月) 21:33:45.52
>>538 いや、OSの仕事でもないよそれ・・・。
質問です 今DXライブラリの通信を利用してクラスを送り、受信側の同じクラスにコピーして、メンバーを表示するというプログラムを書いているのです。 現在コピーするクラスは int a[9]が5つ std::string a[9][30]が1つ クラスのメンバーを持っています これを以下のように受け取っているのですが Class Class_copy Class *test; test=new Class; NetWorkRecv( NetHandle , Chara_test , DataLength ) ; // データをバッファに取得 Class_copy=*test; これを実行したときにstd::string a[9]が8文字以上のひらがな・漢字・全角カナを受け取ると表示したときに凄く文字化けしてしまうのです 他のint型メンバーや7文字以下のstringは何も問題がないのですが・・・ 一体何が原因なのでしょうか
コピーコンストラタクタ書けよ
スイマセンコピーコンストラクタはデフォルトを使っています
string a[9]なのかstring a[9][30]なのかはっきりしろ
そのNetWorkRecvとやらは、コピーコンストラクタを呼んでデータをコピーしているのか? std::stringをビットごとにコピーしても動かないぞ
548 :
536 :2011/04/04(月) 22:48:22.74
>>542 あ、そうなんですか・・・?
WDKというデバイス開発用キットを落として入れてみたりはしたんですが、
ネットワークプログラミング自体に接するのが初めてでして、そういったライブラリが既にどこかに存在するのかと推察しておりました。
よろしければご教授頂けませんか?
>>546 ちょっと書き方が悪かったです。string[9][30]のstring[1][30]~[9][30]に受け取った文字です
動作としてはこんな感じです
a[0][30]="ああああ" 普通に表示
a[1][30]="ああああああああ" 表示すると文字化け
>>547 NetWorkRecv(int NetHandle, void *Buffer, int Length)は NetHandle の指し示す接続先からDataLength分データをバイト単位でBufferの示すアドレスにコピーする、とのことです
std::stringはビットごとにコピーしても動かないのですか?7文字以下だとちゃんと表示されるのですが・・・
もしかしてこいつchar[]と一緒だと思ってないか
シリアライズとかしたほうがいいんじゃないか そのまま突っ込むのはさすがに無理がありすぎるだろ
とりあえず言語の勉強のほうが先だと思う
>>550 便利なcharぐらいの印象です。
>>551 シリアライズですか。ちょっと調べてみよう・・・
>>553 charは文字で、stringは文字列だぞ
言わば、string == char[]
>>554 いくらなんでもそこは等号じゃないだろう。
>>553 せっかくだから Plain Old Data についても調べておくといいかもしれない
ヒープを使わない文字列クラス教えてください。
>>555 ≒とか付けるの面倒だったんだ察してくれw
stringは実装的にはポインタや付加情報を保持する形になっているんだから、 そのまま送ってデータが届くわけがないだろう。 どんなテレパシーなんだよ。
俺とお前はテレパステレパスだというのに
562 :
のみねーと ◆myadMFZ/7k :2011/04/05(火) 08:25:45.87
r、 |:.:.:.:.〈;;;;;;;ノ :.:.:.:.ヽ
_/△ハ,,__ / ハ !:.:.:.:.:.:.::.:.:.:.:.:.:... :.:.:.:.ヘ
/: : : : : :/ ||:.:i/'ーリ―- 、_:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:. :.:.:.:.:.:.ハ
//: : /: :.:.ト=': : : : :/: : : : : : :. ̄`''ー- 、:.:.:.:.:.:.:.:.:... . .:.:.:.:.:.:!
/ /: : /:.:.:.:.:/: :./: : : /: : : :./: : :/:/: /!: :.i::::``.、:.:.:.:.:.:.:.:.:.:.:.:.:.:!
. /: :./:.:.:.:.:.:! : /: : : / : : : /: : :/:/!:./ |:.:.l|: : :.:.::::\:.:.:.:.:.:.:.:.:.:.|
/Vlハ|/!/!|: : !: : : :! : : :.,'!: :.:/:/ |,' |: :|!: :! : i:.:.::::ヽ.:.:.:.:.:.:.:.:l
,イ /|: :.|: : : :|: : : :.!|: :/:/ |! .|:.リ|: :|:.:.:|: : : : :ハ:.:.:.:.:.:.!
. / / ! ,r|: : : :|: :.'"丁/ ̄` |! !,'十ァ!、:.|: : : :.|: !:`! _,/
|:.! |: : : :| ,rfj ̄ヾ、 ! / |ム」_:リ!: : :.,':.:|:::「
| ト.|: : : :K {| ::::::リ l / ,イ}:::::::ハ,!: :.:/:.:.,'::::|
V:.ハ: : :.| ゛ー '' K.__,/ }:.:.:/:.::/::::リ
V: |: : :ト . xxxx ,. `"''" //}:::/: :.,' ただちに逃げてください...
V:ハ : |:::\ __ "'''''' /イ:::::/: :./
リハハヽ-t`/ \ _,. イ//l/!/|/!
,..、 / /~\ ヽ‐、 / / / リ
/: : :\ _ __,.ィ| イ ,.へ `< ヽr‐ァ―=‐、
くr! : : : : : }フ´ \ ̄ハ:.:.:.:ハ イ ,、〆``ー /:.:/::/ ハ
. |ト、: : : : :/ ヘ::|: !.:.:.:ハ ∨ ̄ / .:/::/ / i!
ただちににげろのガイドライン
http://www.geocities.jp/ust7800870/index.html ドイツ4月7日予想
ttp://www.geocities.jp/ust7800870/img/2011_04_07.jpg http://www.dwd.de/
ダウンキャストするのとunion使うのどっちがいいですか?
まずは評価基準を明確に示せ。
>>564 ダウンキャストとunionで同じ事をするソース見せて。
>>564 unionと同じようなことをさせるキャストはダウンキャストは呼ばないんじゃないか?
>>566 引数でバリアント型を含むクラスを使うか目的のクラスにキャストして使うか迷っていました
>>567 たしかにそうですね、、、失礼しました
struct Boo{ int a,b,c; char* p; }; Boo boo = {}; ・・・ boo = Boo(); //これ 構造体をこのようにクリアするのはまずいですか? 他にいい方法ありますか?
コンストラクタ書けばいいよ
PODにしたいです
memcpyでいいよ
PODなら別にいいじゃん
なにをきにしているんだ
個人的にはVTABLEもってないならMemset大丈夫だとおもうんだけど、どうかな??
memsetするのはC厨か老害
>>569 Boo boo={0,0,0,""};
でいんじゃね?
Boo boo={0};でいい
使った後に値をクリアする話だろ PODならmemsetで問題なし
あんまりいい方法じゃないけど、 Boo ForClear ={0}; Boo Using; //dododo Using = ForClear; とか・・・。
callocした後に何回でもmemsetで初期化してやる
>>581 ForClearはstatic constにしておけば最適化で即値代入になってくれるんじゃね。
>>583 横からだけど、それいいね。
一回初期化されればあとはメモリのコピーコストくらいか。スタックもそんなに食わないし。
バッドノウハウには違いないが、悪くないかも??
ほんといいね。思いつかなかった memsetはどんなにコンパイラが最適化しようと ループを使わざるを得ないから効率が悪い。 実行途中の初期化はそれ使うことにする。
>>575 ,579
ポインタや浮動小数点数は memset() で 0 埋めしても 0 になるとは限らないぞ。
587 :
デフォルトの名無しさん :2011/04/08(金) 01:04:19.19
>>585 ダウト〜
バウンダリでサイクル合わせたりアンロールもできる
アセンブラ覗いてみればわかること
>>568 引数でバリアント型を含むクラスを使うのと目的のクラスにキャストして使うのとで同じことするソース見せて。
BOOST_PP_IIF(BOOST_PP_EQUAL(n, i), HOGE, FUGA) とすると、 BOOST_PP_EQUAL(n, i) が展開されずに BOOST_PP_IIF_BOOST_PP_EQUALと結合されてしまうんですがどうにかしてBOOST_PP_EQUALは使えないんでしょうか。
BOOST_PP_EQUALに数字以外を入れるな 次からはboostスレできこうね
592 :
591 :2011/04/08(金) 05:04:10.15
ああ、ごめん。ちゃんと見てなかったわ。 無理ね。
これはどこが間違えかわかりますか? テキストファイルを読み込んで、行へ分割して、出力しているのですが。 まれに、x行目(x+1)行目と改行なしで続けて出力されます。 #include <string> using namespace std; #define CashSize (1<<18) int main() { char *fn = "sample.txt"; FILE *fp = fopen( fn , "rb" ); FILE *fq = fopen( "outfile.txt" , "wb" ); string Cash; unsigned int m, n; while ( !feof(fp) ) { m = Cash.size(); Cash.resize( m + CashSize ); n = fread( &Cash[m], 1, CashSize, fp); Cash.resize( m + n ); m = 0; while(1) { for( n=m; n<Cash.size(); n++ ) if(Cash[n]=='\n' || Cash[n]=='\r') break; if( n >= Cash.size() ) break; if(m<n) { string t = Cash.substr(m,n-m)+"\n"; fwrite( &t[0], 1, t.size(), fq); } m=n+1; } Cash = Cash.substr(m); } fwrite( &Cash[0], 1, Cash.size(), fq); fclose(fp); fclose(fq); }
C/C++の行読み込み関数を使うと遅いので、バッファへまとめて読み込んで処理したいんです。
>>593-594 ぱっと見ではよくわからんが、その程度の処理でよくわからんコードになってる
というのがまず間違いだろうな。
「長いソースを貼るときは」
>>5 変数名をちゃんとつけて、使い回しをやめろ。
エラーチェック抜けてる。
× cash ○ cache そもそも
>>594 を見ると「キャッシュ」じゃなくて「バッファ」でしょ。
#include <cstdio> 抜けてる。
CashSize は unsigned int const で。
それ以前に、何を見て「遅いので」と言ってるのかがまず怪しい気がしてきた。
書き直しました。 #include <stdio.h> #include <string.h> #define BuffSize (1<<10) int main() { FILE *fp = fopen( "sample.txt" , "rb" ); FILE *fq = fopen( "outfile.txt" , "wb" ); char buff[BuffSize+1]; int readiti=0, enditi; while ( !feof(fp) ) { enditi = readiti + fread( &buff[readiti], 1, BuffSize-readiti, fp); char *p=&buff[0], *q, *endp=&buff[enditi]; while(1) { for( q=p; q!=endp; q++ ) if(*q=='\n' || *q=='\r') break; if(q==endp) break; if(q!=p) { fwrite( p, 1, q-p, fq); fwrite( "\n", 1, 1, fq); } p=q+1; } readiti=(int)(endp-p); memmove(buff, p, readiti); } fwrite( buff, 1, readiti, fq); fclose(fp); fclose(fq); }
×間違え ◯間違い それはさて、先ずは非バッファ版を作って正常に動作させ、速度の検証をするべきだな。 その程度のコードだと、一行ずつ処理しても殆ど遅くならないと思う。
非バッファ版っていうと、こんなもんでいいんじゃない?(動かしてないけど) #include <fstream> #include <cstdlib> int main() { std::ifstream input("sample.txt"); std::ofstream output("outfile.txt", std::ios::binary); output << input.rdbuf(); output.close(); return (input.good() && output.good()) ? EXIT_SUCCESS : EXIT_FAILURE; }
あ、 input.close() 抜けてた。まぁいいか。
なるべく高速に行分解をしたいということなんです。
高速化の必要性うんぬんは質問に関係ないだろ
>>600 高速性云々はさておき
入力ファイルは「行で区切られている」からファイルを「そのままコピー」するコードを書けばいいはずだが書かれたコードはそうなっていない
それ以外の要件があるんじゃないのか?
>>600 これで速度に不満があるのか?
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
std::ifstream input("sample.txt");
std::string line;
while(std::getline(input, line))
std::cout << line << std::endl;
return input.good() ? EXIT_SUCCESS : EXIT_FAILURE;
}
二倍は速い。独自のほうが。 #include <iostream> #include <string> #include <vector> #include <time.h> #define bufSize (1<<20) using namespace std; char *buf; void vecset1(char *fn, vector<string> &vec) { FILE *fp = fopen( fn , "rb" ); vec.resize(0); while ( !feof(fp) ) { fgets(buf,bufSize,fp); vec.push_back(string(buf,strlen(buf))); } fclose(fp); } void vecset2(char *fn, vector<string> &vec) { FILE *fp = fopen( fn , "rb" ); vec.resize(0); int readiti=0, enditi; while ( !feof(fp) ) { enditi = readiti + fread( &buf[readiti], 1, bufSize-readiti, fp); char *p=&buf[0], *q, *endp=&buf[enditi]; while(1) { for( q=p; q!=endp; q++ ) if(*q=='\n' || *q=='\r') break; if(q==endp) break; if(q!=p) vec.push_back( string(p,q-p) ); p=q+1; } readiti=(int)(endp-p); memmove(buf, p, readiti); } vec.push_back( string(buf,readiti) ); fclose(fp); } int main() { buf=new char[bufSize]; char *fn="D:/desktop/行をシャッフル/sample.txt"; vector<string> vec; int cl; cl=clock(); vecset1( fn, vec ); cout<<(clock()-cl)<<endl; cl=clock(); vecset2( fn, vec ); cout<<(clock()-cl)<<endl; }
Cならsetvbuf() C++ならstreambuf::pubsetbuf()使ってみたら
C++はもっと遅かった。C++8157clock、バッファから分割3609clock。 #include <fstream> #include <time.h> #define bufSize (1<<20) using namespace std; char *buf; void vecset1(char *fn, vector<string> &vec) { fstream fp(fn); string line; vec.resize(0); while(getline(fp, line)) vec.push_back(line); fp.close(); } void vecset2(char *fn, vector<string> &vec) { FILE *fp = fopen( fn , "rb" ); vec.resize(0); int readiti=0, enditi; while ( !feof(fp) ) { enditi = readiti + fread( &buf[readiti], 1, bufSize-readiti, fp); char *p=&buf[0], *q, *endp=&buf[enditi]; while(1) { for( q=p; q!=endp; q++ ) if(*q=='\n' || *q=='\r') break; if(q==endp) break; if(q!=p) vec.push_back( string(p,q-p) ); p=q+1; } readiti=(int)(endp-p); memmove(buf, p, readiti); } vec.push_back( string(buf,readiti) ); fclose(fp); } int main() { buf=new char[bufSize]; char *fn="sample.txt"; vector<string> vec; int cl; cl=clock(); vecset2( fn, vec ); cout<<(clock()-cl)<<endl; cl=clock(); vecset1( fn, vec ); cout<<(clock()-cl)<<endl; }
>>606 は、先頭にこれが抜けてた。
#include <iostream>
#include <string>
#include <vector>
入力の所要時間だけ比べて二倍速い(キリッ とか言われてもなぁ。 そもそも、その比較じゃディスクキャッシュも効いちゃうのだけどね。
それでvecset2の行分割は、 どこが間違えているのかわからないっていう質問なんですが。 およそテキスト10Mで2カ所ほど、改行が無くなって一つの行になにってしまいます。
611 :
606 :2011/04/08(金) 13:28:33.22
ディスクキャッシュと、vectorのメモリ確保で差が出てしまうから、 繰り返し速度を測ったけど、標準は圧倒的に遅い。 int main() { buf=new char[bufSize]; char *fn="sample.txt"; vector<string> vec; for(int n=1; n<20; n++ ) { int a,b,x; x=clock(); vecset1( fn, vec ); a=clock()-x; x=clock(); vecset2( fn, vec ); b=clock()-x; cout<<n<<"回目: C++行読み込み "<<a/CLOCKS_PER_SEC<<"sec. 独自 "<<b/CLOCKS_PER_SEC<<"sec.\n"; }}
>>606 手元の Cygwin g++ 4.3.4 の -O3 で 10MB ぐらいのテキスト読ませてみたら、
fstream+getline() がだいたい 1.5 倍ぐらい時間かかってた。
順番入れ替えたり何度か繰り返してみたけど、それぐらいで落ち着く。
>>606 vecset1() と vecset2() の結果を入れる vec を2つにわけて比較してやれば
どこで間違ってるかわかるんじゃないの?
>>605 バッファサイズと関係なく遅かったC++行読み込み。
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <time.h>
#define bufSize (1<<20)
using namespace std;
char *buf;
void vecset1(char *fn, vector<string> &vec) {
fstream fp(fn); fp.rdbuf() -> pubsetbuf(buf, bufSize); string line; vec.resize(0);
while(getline(fp, line)) vec.push_back(line); fp.close(); }
void vecset2(char *fn, vector<string> &vec) {
FILE *fp = fopen( fn , "rb" ); vec.resize(0); int readiti=0, enditi;
while ( !feof(fp) ) {
enditi = readiti + fread( &buf[readiti], 1, bufSize-readiti, fp);
char *p=&buf[0], *q, *endp=&buf[enditi];
while(1) {
for( q=p; q!=endp; q++ ) if(*q=='\n' || *q=='\r') break; if(q==endp) break;
if(q!=p) vec.push_back( string(p,q-p) ); p=q+1; }
readiti=(int)(endp-p); memmove(buf, p, readiti); }
vec.push_back( string(buf,readiti) ); fclose(fp); }
int main() {
buf=new char[bufSize]; char *fn="sample.txt"; vector<string> vec; int n,a,b,x;
for(n=1; n<20; n++ ) {
x=clock(); vecset1( fn, vec ); a=clock()-x;
x=clock(); vecset2( fn, vec ); b=clock()-x;
cout<<n<<"回目: C++行読み込み "<<a/CLOCKS_PER_SEC<<"sec. 独自 "<<b/CLOCKS_PER_SEC<<"sec.\n";}}
>>613 どこが間違えるか比べるのは既にやったのですが。原因がわからないです。ほぼ一致します。
5メガ程度だと完全一致する事もあって10メガだと2個程度、間違えたりします。
>>613 サンクス。いつもはボーランドだけど、VC2008で最適化したら1.657倍だった。
>>610 ざっと見た感じ そのコードはバッファの先頭に改行がきたら出力されないでしょうね
テキストの先頭に改行がある場合と、バッファリングで改行がバッファ先頭にきたら改行無視される
vecset2は、改行のみの行はスルーする仕様なんですが。それは別ですか。
cygwinはラッパが遅い。 それはさて、>606は空行を飛ばしてしまうし、末尾一行余計に追加している。
仕様かよw
改行は正確に扱うと、手間がかかるので、空行はスルーしました。目標のためには空行は無視してかまわないので。
>>619 ここですか?
元テキストが改行で終わっていない場合、未出力部分が残ってしまうと思うのですが。
> vec.push_back( string(buf,readiti) ); fclose(fp);
いや、途中の空行は無視して、末尾に空行を追加すると言う仕様でいいならいいんじゃない? 個人的には有り得ないけど。
>>623 おまけに、偶然バッファの先頭に改行が来たらそいつも無視する仕様ってことで一つw
>>623 これでいいですか。
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <time.h>
using namespace std;
#define bufSize (1<<20)
char *buf;
void vecset(char *fn, vector<string> &vec) {
vec.resize(0);
FILE *fp = fopen( fn , "rb" );
int readiti=0, enditi;
while ( !feof(fp) ) {
enditi = readiti + fread( &buf[readiti], 1, bufSize-readiti, fp);
char *p=&buf[0], *q, *endp=&buf[enditi];
while(1) {
for( q=p; q!=endp; q++ ) if(*q=='\n' || *q=='\r') break;
if(q==endp) break;
if(q!=p) vec.push_back( string(p,q-p) );
p=q+1; }
readiti=(int)(endp-p); if(readiti) memmove(buf, p, readiti); }
if(readiti) vec.push_back( string(buf,readiti) ); fclose(fp); }
int main() {
buf=new char[bufSize]; char *fn="sample.txt";
vector<string> vec;
//速度測定
double x=clock(); vecset( fn, vec ); cout<<(clock()-x)/CLOCKS_PER_SEC<<"sec.\n";
//出力
fstream fp("outfile.txt", ios::out ); for( int n=0; n<vec.size(); n++ ) fp<<vec[n]<<endl; fp.close(); }
バッファサイズを超えた長さの行が入力されたら出力されない部分がでてくる?
ありがとうございました。解決したと思います。
>>625 のコードで75MBのテキストで成功しました。
>627 バッファを越える長さの行があると破綻するね。
できましたよ。これで正常動作するはず。 #include <iostream> #include <string> #include <vector> #include <fstream> #include <time.h> using namespace std; #define bufSize (1<<6) char *buf; void vecset(char *fn, vector<string> &vec) { vec.resize(0); FILE *fp = fopen( fn , "rb" ); int readiti=0, enditi; string bigstr; while ( !feof(fp) ) { enditi = readiti + fread( &buf[readiti], 1, bufSize-readiti, fp); char *p=&buf[0], *q, *endp=&buf[enditi]; while(1) { for( q=p; q!=endp; q++ ) if(*q=='\n' || *q=='\r') break; if(q==endp) break; if(q!=p || bigstr.size()>0 ) { vec.push_back( bigstr + string(p,q-p) ); bigstr.resize(0); } p=q+1; } readiti=(int)(endp-p); if( readiti==0 ) continue; if(p!=&buf[0]) { memmove(buf, p, readiti); continue; } bigstr += string(p, readiti); readiti=0; } if( readiti>0 || bigstr.size()>0 ) vec.push_back( bigstr + string(buf,readiti) ); fclose(fp); } int main() { buf=new char[bufSize]; char *fn="sample.txt"; vector<string> vec; double x=clock(); vecset( fn, vec ); cout<<(clock()-x)/CLOCKS_PER_SEC<<"sec.\n"; fstream fp("outfile.txt", ios::out ); for( int n=0; n<vec.size(); n++ ) fp<<vec[n]<<endl; fp.close(); }
おつ
そんな入力ロジックで大丈夫か?
ていうか、f***を使ってる時点でバッファリングされてるんだから そんな神経質になる必要あるんかな。
最もコードが簡略になるように作り、速度を測ったのちに改変するのが良い。
bitsetのように、[]で代入と参照するにはどうしたらいいですか。 #include <iostream> #include <bitset> using namespace std; int main() { bitset<100> a; a[1]=3; cout<<a[1]<<endl; }
何を[]で代入と参照させるんだ?vector?
すみません。一番最後の行の実装方法がわからないです。 #include <iostream> using namespace std; class bitset_mini { int x; public: bool operator [] ( unsigned int n ) { return (x>>n)&1 ; } }; int main() { bitset_mini z; cout<< z[1] <<endl; z[1]=3; //これの動かし方がわからない。 }
>>638 C++では無理。
C#のプロパティならできる。
bitsetでは出来てるのですが?
boolを返すんじゃなくてproxyはさめ
くわしく
無理矢理出来た。これが正解なのだろうか? #include <iostream> using namespace std; template <class cls> class one_bit { cls *x; unsigned int k; public: one_bit( cls *y , unsigned int n ){ x = y; k=n; } void operator = ( int n ) { *x |= (n&1)<<k ; } //代入 operator cls() { return ((*x)>>k)&1; } //表示 }; class bitset_mini { int x; public: one_bit<int> operator [] (unsigned int n) { return one_bit<int>(&x, n); } }; int main() { bitset_mini z; cout<< z[1] <<endl; z[1]=3; cout<< z[1] <<endl; }
templateいらないか
例外安全のためにと例外を送出しないようにするコードをよく見ます void hoge() throw() {} これにはどういう意味があるのでしょうか? - 例外が発生するくらいなら強制終了させる - ただ例外が発生し得ないことを明示しているだけ - その他
>>646 意味については自分で答えが出てるみたいだけど、ほんとは何が聞きたいの?
>- 例外が発生するくらいなら強制終了させる Visual C++ではunexpectedがまともに動きませぬ
例外安全、か?
メンバ関数についての質問 処理が同じconstメンバ関数と非constメンバ関数をもっとスマートに記述する方法ありますか? class Hoge { public: string & GetName() { return this->name; } const string & GetName() const { return this->name; } private: string name; }; 「return this->name;」の部分がもっと複雑だったばあいの処理を一箇所にまとめたいんだけど・・・
return const_cast<string &>(const_cast<const Hoge *>(this)->GetName());
最初はstatic_castでいんでね const string & GetName() const { return this->name; } string& GetName() { return const_cast<string&>( (static_cast<const Hoge*>(this)->GetName() ) }
>>656 設計を見直すために参考になるソース等を頂けるとうれしいです
>>656 あーいや、ちょっとソースが見づらくなるなと思っていたんだ
例があくまでも例なのかもしれないけど、データメンバの参照を返すのってどうなのかな、と思わなくも。
>>658 別にcppの中に掩蔽してしまえばいいんでね?
そもそも割と有名なイディオムだからそんなに可読性は落ちない
気持ち悪く思うのは最初だけ
>>659 非const側の関数の問題?
この関数を削除して、変数nameを操作する関数をHogeクラスに追加するのが面倒だと思った
危険性は理解しているし、使いどころを分けているから大丈夫
>>660 そういうものか。これからそうするようにしてみるよ
662 :
655 :2011/04/12(火) 19:01:44.37
>>659 に指摘していただいたアクセッサ・・・というかミューテータもかな
自分は大体の場面で下記のような定義をするんだけど、
Outerクラスについてのレビューをして頂けますか?
class Inner
{
public:
typedef boost::shared_ptr<Inner> shared_ptr;
typedef boost::shared_ptr<const Inner> shared_const_ptr;
shared_ptr Create() { return shared_ptr(new Inner()); }
};
class Outer
{
public:
Outer()
: inner(Inner::Create()) {}
void SetValue(int value) { this->value = value; }
int GetValue() const { return this->value; }
// void SetName(const string & value) { this->name = value; }
string & GetName() { return this->name; }
const string & GetName() const { reeturn this->name; }
void SetInner(const Inner::shared_ptr & value) { this->inner = value; }
Inner::shared_ptr GetInner() { return this->inner; }
Inner::shared_const_ptr GetInner() const { return this->inner; }
...
663 :
655 :2011/04/12(火) 19:03:52.32
... private: int value; string name; shared_ptr inner; }; nameの変更を保護したいばあいは 「string & GetName() { return this->name; }」 を定義しない nameを保護しないで、string型のメンバ関数を自由に使いたいばあいは 「void SetName(const string & value) { this->name = value; }」 を定義しない 独学な部分が多々あるから、何かとんでもないミスをしていて、自分がそれに気付いていないのかもと思った
これだけだと判断に苦しむが 存在しない参照が残る可能性を残すデメリットよりも、 コピーによるデメリットが大きいかどうかじゃないだろうか 実際参照を返すことが最良な場合だってあるわけだし ところで蛇足ではあるがCreateはstaticでは?
参照を用いたメソッドチェーンを行いたい場合以外の用途が思いつかなかった。
>>662 って、それ以外になんかのメリットあるのかな。
そう記述することの意図が汲み取れなくてごめん。
666 :
655 :2011/04/13(水) 00:23:50.70
>>664-665 レスサンクス
[修正]
shared_ptr Create() { return shared_ptr(new Inner()); }
↓
static shared_ptr Create() { return shared_ptr(new Inner()); }
shared_ptr inner;
↓
Inner::shared_ptr inner;
変数nameの非const GetName() については、例えば outer->GetName().replace(... とかそんな感じで使用することを想定しています
非const参照を得る方法を提供しないで、Outerクラスで同じ関数を用意するべきですか?
実際は非const側の GetName() はほとんど使わないのですが
void GetName(string * pOutput) {
*pOutput = this->name;
}
とかの方がいいですか?
>>666 だからさ、どうするべきかってのは要求に応じて変わるんだよ。
要求や心配している点を示さずに「するべきですか?」とか「〜の方がいいですか?」とか
聞かれても何とも言いにくい。何を言っても後で「実は・・・」とか出てきそうでな。
668 :
655 :2011/04/13(水) 03:45:11.72
std::string型メンバ変数のアクセッサの定義について、定石や「自分ならこうする」というこだわりを知りたい 第一要求として速度重視。その次にコードの見易さ
>>668 その要求なら参照返しでFA。
コピーしたら遅くなるし、コードの見易さも変わらないからね。
放り出した参照がどこかで握られてるかもしれないっていう点で
見易さが損なわれてるかもしれないけど、速度のほうが優先みたいだし。
参照の危険性を示すために NameRef() とかにしとけばいいんじゃない? 速度が要らないところで安全にコピーを返す Name() も両方付けとくとか。
PHPのコードを実行できる、C++用のDLLってありますか。 JavascriptではSpiderMonkeyとかV8はありますが。
>>666 メソッドチェインが使いたかった、と書けばいいのに
>>666 質問の対象範囲外だとは思うけどまずはメンバのアクセサ提供する必要があるのかを問題にするべきだと思う。
特に shared_ptr を外部から設定できるとか NULL 設定されてもいいのかよ、みたいな。
メンバの参照さらしたりセットできるってことはクラス内で常にメンバが満たしているべき条件が保証できないかもしれない。
複数個の可変長データを、バッファchar *buf = new char [1<<24]へ記録したいです。 何かいいライブラリありますか。OSなどがおこなうメモリ管理と同じような事と思いますが。
vectorに突っ込めばいいんじゃね?
vector<string>とかですか? メモリの再確保をしたくないのですが。 速度のため。
ロックのかかっている領域は●として。 確保したメモリ全体を ○○●●○○○○●○○●●●○○○として。 白い○部分から、必要なメモリを確保してきたいって事です。 空きが無くなったら、登録を外して外部記憶へ書き出します。
速度を気にするならC++をやめろよ
計測して、アルゴリズムを変えて、それでもまだ本当にメモリ確保がボトルネックになっているなら考えればいいことだな
速度を気にするならどの言語を使えばいいの C以外だと
アセンブラでおk
>>681 動的確保でやってみてボトルネックになっていてから、こだわることにします。
2^24B=16MBくらい一括でnewなりmallocなりできると思うんだが。 それともOSが載ってなかったりするの?
687 :
684 :2011/04/13(水) 21:58:02.39
しかしSTLは最大2倍まで無駄にメモリ確保するのとと、一度確保されたら縮まないという欠点が。 16M分使うと、32M確保してたら、その差の部分をバッファに使った方が得なんですが。
>>687 いやだから、気になってるのがSTLなら、いきなりアロケータを手作りせずに
単にmalloc()やnew使えばいいでしょ
じゃあ初めに固定長で必要な量取っとけばいいじゃない。 そして内部で切り分けたらいいよ
>>689 その切り分けをして空いた領域を取得する上で
フりーリスト管理なりベストマッチサーチなりの
アルゴリズムがいるわけで、要するにやることがメモリアロケータと全く一緒
>>687 CPUがひまそうなときに縮めればいいと思うよ。縮められるから。
>>687 これだけのことを把握して実測できる技術力を持ちながら、こんなところでこんな聞き方しかできないアンバランスさ。
環境の話が全くないからnewかmalloc使って桶で終わる
boostのメモリ管理使えばどうだろう
>>687 std::vector 使うとしても reserve() するとか swap() による shrink to fit を使うとかすれば
そこらへんの問題もどうにかなるだろ。
pool_allocatorじゃないの
>>694 ,697
boost::pool は固定長で大量の確保を高速化するものだったような気がする。
>>676 ,679 みたいな可変長の要求にも役に立つのかね?
>>698 それはfast_pool_allocatorで実際はpool_allocatorが役に立つ。
>>679 >って事です。
ここまでのはSimple Segregated Storageってのでそのまま実現できる。boost::pool_allocatorも同じ方式
>空きが無くなっ
これは自分で実装する必要があると思う
速いCPUで速いメモリのマシンに買い換えろ が正解でないか?
今CPUもメモリもビデオカードも安いから正直買い換えが苦にならない
C++でオープンソースの画像ビューアで書庫が扱えるものはありませんか?
すみません。書庫のロード部分が知りたいので、オープンソースのMP3プレーヤーでもかまいません。
706 :
655 :2011/04/14(木) 17:31:51.49
亀レスですまん
>>669 実際に参照を多用しているんだけど、結構危ないのかなぁと思ったんだ
でも、外部からメンバ参照を操作されたくなければ string & GetName() 非const を提供しなければいい話だし
>>672 でも言われている通りメソッドチェインが使えると効率がいいからなぁ
>>675 一応だが、
>>662 のソースコードではshared_ptrの参照は非constでは返してない。
shared_ptrでの戻り値は習慣的に値返ししているけど、
「const Inner::shared_const_ptr & GetInner() const { ... } 」
みたいに const shared_ptr & を返すのもアリなんですか?
マルチスレッドだと値返しは危ないという理解で合ってますか?
>>670 関数名は考慮が必要かもしれませんが、
「const string & GetNameA() const」が存在する状況でコピーを返す関数、例えば
「void GetNameB(string * pName) const」は必要ありますか?
参照を取得できれば、外部から「string s(outer.GetNameA());」といった感じにコピーできるので・・・
707 :
655 :2011/04/14(木) 17:32:16.16
亀レスですまん
>>669 実際に参照を多用しているんだけど、結構危ないのかなぁと思ったんだ
でも、外部からメンバ参照を操作されたくなければ string & GetName() 非const を提供しなければいい話だし
>>672 でも言われている通りメソッドチェインが使えると効率がいいからなぁ
>>675 一応だが、
>>662 のソースコードではshared_ptrの参照は非constでは返してない。
shared_ptrでの戻り値は習慣的に値返ししているけど、
「const Inner::shared_const_ptr & GetInner() const { ... } 」
みたいに const shared_ptr & を返すのもアリなんですか?
マルチスレッドだと値返しは危ないという理解で合ってますか?
>>670 関数名は考慮が必要かもしれませんが、
「const string & GetNameA() const」が存在する状況でコピーを返す関数、例えば
「void GetNameB(string * pName) const」は必要ありますか?
参照を取得できれば、外部から「string s(outer.GetNameA());」といった感じにコピーできるので・・・
708 :
655 :2011/04/14(木) 17:33:42.34
重複投稿したかも。失礼しました
ZIP書庫のZIP書庫内にテンポラリ作らずアクセスする方法ありますか?
方法はあるよ。 ただ、それを行うライブラリとかの存在はしらない。
zlibとzip(32,64)は別ですが。avi、mp4、flvと動画エンコードのような。
>>686 パワーポイントの方は見た事あったけど、動画は初めて見たわ。
面白かった。ていうか、じゃんじゃんうっせーよw
zlibって展開する所だけなのね てっきりzipの読み込みまで入っているのかと思ってた 一応サンプルにminizipってのがあるらしいから、参考にはできるかもしれないけど 7zipもzip使えるみたいだから、そっちの方が楽かな?
書庫の書庫が読めるサンプル、コード見つからないです・・・
再帰って知ってる?
>706 言いたかったのは SetInner(Inner::shared_ptr()); されてもいいのか?って事。使う時に毎回有効性のチェックする? もっと言うとクラスのインタフェースはその機能によって定められるべきで メンバによって定められるべきではないと思う。本当にアクセサが必要なの? >const shared_ptr & を返すのもアリなんですか? 個人的にはナシ。 >マルチスレッドだと値返しは危ないという理解で合ってますか? いや、まずいのは参照返しの方だろ? 実体より寿命の長い参照に設定された場合が駄目なのでマルチスレッドでなくても 駄目な場合は発生しうる。 >「void GetNameB(string * pName) const」は必要ありますか? >670 が言っているのは string GetNameB() const だと思う。 そして個人的には const string & 返すのがあれば不要だと思う。 むしろ void GetNameB(string &name) const を作るかもね。
>>719 自分で調べる気一切ないみたいだから諦めた方がいいよ
動作中のプログラムだけでいいので、 マウントとのように動作するライブラリを作れば 何階層でも読みに行けることになる。
setjmpとlongjmp関連についての質問です。 C++の例外と相性がわるいと書かれている記事をみかけました。 リンクしたいC言語で書かれたいライブラリのとある関数のなかで、 setjmpとlongjmpが使用されておりました。 実際には例外処理てきな使われです。 どのような状況で利用するとC++的にはまずいのでしょうか?
>>722 例外と共存させるとデストラクタが呼ばれないので拙い(。
Cで書かれたいライブラリの中で閉じている分には無関係。
longjmp()でのスタックアンワインドではデストラクタが呼ばれないのが問題 if (setjmp(...) == 0) { tryブロック相当 longjmp()を呼ぶかもしれないCの関数を呼んだりとかする } else { longjmp()がよばれた。エラー処理とかする } こんな感じの書き方になると思うけど、上のtryブロック相当のところで デストラクタ呼び出しが必要なC++コードを記述してしまうと デストラクタが呼ばれなくなってしまう 逆にそうしなければ、基本的には問題ないはず
726 :
709 :2011/04/15(金) 12:39:02.76
ZIPの書庫の書庫へのアクセス教えてください。 MP3や画像ビューアなど、テンポラリなしでダイレクトに読みに行くのがあると思うのですが。
zipは、格納されてる個々のファイルにはシークでランダムアクセス可能な 構造になってるけど deflate圧縮されたファイルの中身は無圧縮zipでない限りは ランダムアクセス不能なので シークエンシャルにロードできるような形式でなけば 結局メモリかファイルに一度全体を展開する必要はある でかいAVIのようなものをを全部オンメモリ展開するのははた迷惑なので、 結局一時ファイルがベストという判断もありえるよ
>>723-724 レスありがとうございます。
C++の例外機構内で使用しなければよさそうですね。
ありがとうございました。
アーカイバとコンプレッサーはべつやがなーってことでいいのかい?
>>728 いや、実際に問題になるのはデストラクタの利用。
例外送出時の問題はその一例。
>>730 >>724 さんの例のようにデストラクタを、
呼ばなければならないシーンを飛ばしてしまうことがある。
なので利用するときはC++での利用は推奨されない。
また、利用先のCライブラリないで閉じているならば問題ではない。
ということでよろしいでしょうか・・・。
732 :
723 :2011/04/15(金) 13:25:19.34
>>725 あー確かに。例外関係なく、デストラクタを無視しちゃうのが問題だね。
Cで書かれたライブラリ内で閉じている分には関係ないが、
C++のコード内では(事実上)使えないと。
書庫の書庫内を読み取るソースありますか? 5ギガのzipがあり、その中に500メガ〜1000メガの書庫が格納されている場合、 アクセスのたびにテンポラリに解凍しては激遅になります。 書庫形式からダイレクトに読みにいくのは可能なはずなんですが。
ないのでお引き取りください
格納ファイルの先頭からなら、読み込めて、書庫内の書庫のファイルは読み込めないのか。
しかしテンポラリ作らず読んでいそうなソフトもあるが。
>>735 とか。
やっぱ出来るな。 書庫情報には格納前と圧縮後サイズが記録されているから 書庫内の書庫の途中から、ファイルデータを取り出せるはず。
2度目の圧縮で位置がずれるから無理か。あきらめた。
何度も何度も馬鹿の一つ覚えで質問して自分の脳みそないのかよって感じだが 君が探すべきなのはテンポラリを使わない方法では「なく」、一度作成したテンポラリを 再利用する方法じゃないのかね?
>>739 横レスだが、
質問者の処理の対象となる書庫は、
毎回違うのかもしれんよ。
そのへんの考察もできずに、上から目線とは
目くそ鼻くそかもよw
>740 かもしれんね。だとすれば >727 で話は終わっている。
742 :
デフォルトの名無しさん :2011/04/17(日) 01:08:27.67
メンバ関数のデフォルト引数にそのクラスのメンバ変数を入れようとしたら invalid use of non-static data member とg++にいわれました 何がいけないんでしょう?
>>742 >何がいけないんでしょう?
エラーメッセージも読めないあんたの頭
いやまぁ言ってることはわかるんだが、理由がわからんw メンバ関数が呼ばれるときには、それを実行するインスタンスはわかっているわけで なぜわかっているはずのメンバ変数をデフォルト引数に突っ込むことができないの? という話です
staticでないメンバ変数はインスタンスごとに存在するわけで メンバ関数のデフォルト引数としてどのインスタンスの変数が使用されるか特定できないじゃないか codepadだと↓ならOK。 class T { public: T(){} ~T(){} static int X; void func(int y=X){ printf("%d\n",y);} }; int T::X=3;
>745 >メンバ関数が呼ばれるときには、それを実行するインスタンスはわかっているわけで 勝手な想像だけど、実現したいことはメンバ関数のオーバーロードで簡単に実現できるのに デフォルト引数でやろうとすると仕様の整合性をとるのが面倒だったから、とかじゃない? 特に仮想関数のデフォルト引数が静的に解決されるってのあたりと。 struct A { virtual void func(int n = 1) {} }; struct B : public A { virtual void func(int n=3) {} }; B b; A *pa = &b; pa->func(); で、3 で呼び出すの?みたいな。
>メンバ関数が呼ばれるときには、それを実行するインスタンスはわかっているわけで 分かるわけがない。 確定するのは呼ばれる時ではなく、呼ばれた後。 仮想関数とかクラスの仕組みを勉強し直せ。
>747 メンバ関数呼ぶ時に this 渡してるんだからそれ使って解決してくれよ、って話じゃないの?
あるクラスの関数の実体はひとつでしょ。 どのインスタンス(の変数)が使われるかなんて動的にしかわからないじゃん。
callする前にthisをスタックに積むんだから、 this->hogeも積めるんじゃないかっていう事かな。
インラインはなるべく使わない方がいい。 CPUのキャッシュは少ない。沢山の関数がキャッシュに載れば弾かれるものも多くなる。 たとえば5カ所で関数を呼び出すなら、インラインにせずキャッシュから読ませた方が速い。
それぞれの段階で段違いに速度差がある。 HDD << メモリ << CPUキャッシュ なるべくメモリを読みに行かせない、なるべくHDDを読みに行かせない点がポイント。 インラインは、コーディングでの見やすさの為に分離した場合は有効。
メンバ関数って暗黙でthisが渡されるからインスタンスごとの動作できるって事でいいんだよね? 俺なんか勘違いしてる?
してないよ
いいんだよ
勘違いしてる。仕様と実装は分けて考えた方がいい
↑バカ
758 :
デフォルトの名無しさん :2011/04/17(日) 22:15:41.63
アウトライン展開
>callする前にthisをスタックに積むんだから、 デフォルトの引数は、コンパイル時に#defineと同じように実命令が変換されるより先に展開されるの。 だからインスタンスがなんなのかなど、コンパイラがその時点で判断できようはずが無い。 なんでそんな簡単なことも理解できないんだ?
仮想関数との組み合わせの話はメンバ変数を参照してもしなくても同じことだから 切り分けて考えるんだ。
foo.bar()をfoo.bar(foo.baz)に展開しろって話してるんだと思ってたけど どうもそうじゃなかったようだ
毎回亀レスで悪い
>>718 > 実体より寿命の長い参照に設定された場合が駄目なのでマルチスレッドでなくても
> 駄目な場合は発生しうる。
ごめん、「実体より寿命の長い参照に設定された場合」っていうのはどんな時?
ちょっと分からなかった
>>747 デフォルト引数は静的な型から決定されるからthis使って解決出来ないじゃん。
>>746 この場合は、B::funcの引数には1が渡されるってこと・・・で合ってるよね?
俺も >761 な話だとずっと思ってるんだが >759 辺りと話が噛み合わないんだ。 仮想関数呼び出しの時の this は動的な型になってるから仮想関数の例とか this どうこう書いたのは良くなかったかもしれない。 コンパイラとしては >761 のように解決すれば良いだけだから実装自体は可能だと思う。 ただし、この場合デフォルト引数を「動的」に解決しているわけだから仮想関数のデフォルト引数が「静的」に解決されるのと 仕様的な整合性が取れていないと思う。 それならってんで、仮想関数のデフォルト引数も動的に解決しようとした場合、仮想関数の解決と同様の仕組みを導入しなければならず メンバ関数のオーバーロードで簡単に実現できることに対してそこまで頑張る必要はない、という判断からデフォルト引数は全て 静的に解決する仕様になったのではないか?、というのが >746 で言いたかったことなんだけど言葉足らずだったかも。 >763 >この場合は、B::funcの引数には1が渡されるってこと・・・で合ってるよね? 合ってる。
言語仕様的に無理なんだから、グダグダ言ったってどうにかなる物でもないだろうに。 こういう無い物ねだりで余計なことに無駄な時間を割くから、 馬鹿の考え休むに似たりって言われるんだよ。
行列って列と行のどっちが一続きの列(ONE PIECE)になるのがふつうですか? 逆にしてしまうとライブラリー使うとき全部変換しないといけなさそうで困りますよね☆
そうかもしれませんねミ☆
ゴムゴムの〜
a a a a a b b b b b c c c c c d d d d d という行列があるとするでしょ? それを格納するのにabcdabcdabcdabcdとするか aaaabbbbccccdddddにするのかどちらが普通ですか? という簡単な質問のつもりですよ?
X[0]=aaaa X[1]=bbbb X[2]=cccc X[3]=dddd
使うライブラリに合わせるだけのことでしょ。 自前でやるならフラグで解釈を切り替えられるようにしておくと、逆行列が瞬時に得られるw
逆行列じゃなくて転置行列じゃねーの?
m11,m12・・・ が普通じゃないの?
使うライブラリーが色々種類あるでしょ。それらは規格を統一してないから どっちが普通かきいているのは明らか。
DirectXの固定機能とシェーダに突っ込む行列はお互い転置。 つまり普通なんてない。 そもそもスレ違い。
しりませんでした ネットで調べてきます あした学校なので ほうか後また書き込みますね。 w
aaaabbbbccccdddddで格納した1次元配列をAPIによって行列操作してあげればいいんじゃないかな?
aaaabbbbccccdddd説がおおいなぁ やっぱパソコンの画面の座標と一致しているのかなぁ。
まあアドレス計算考えたらこっちのほうがとかあるんじゃないかな? まあ普通に4*4の配列でもいいとおもうよ。 コンパイル後は配列のほうが早い場合もおおいらしいしね。
数値解析だと縦の場合もしばしば。 実際には、可変長の配列の配列は作れないから効率重視ならリニアにメモリを確保してオフセット計算して使うことになる。 その場合、縦か横かはオフセット計算の違いだけになる。
>>782 CPUのパイプラインキャッシュが有効になるかどうかという違いもでてくる
784 :
709 :2011/04/18(月) 17:54:29.88
書庫内の書庫内にアクセスするのにキャッシュを使う方法でプログラム作りました。 7-zip32.DLLというのを使いました。 速度を測ると、書庫内のファイルリスト取得(書庫のopen)がボトルネックになっています。 書庫のファイルリストを高速で取得できるライブラリ、ソースはありますか? ヘッダ情報を読むだけでそれほど時間かからないはずですが、このDLLは遅いです。
だったら自分で作れば? ボトルネックが判っててそこまで言うならできるでしょ
786 :
709 :2011/04/18(月) 21:36:34.01
zipには様々な亜種があるんで自作は大変なんですが。 7-zipは多くのフォーマットに対応していいんですが。 7-zipのソースに直接アクセスしてみます。
なんか日本語がおかしいね。
当然のごとく、日本語がおかしい人間はプログラムもまともに組めないよ。
Base64と似たブツ。Base64はエンコード手順が面倒で簡単なエンコード開発した。 #include <iostream> #include <string> static std::string enc64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_"; std::string base64enckai(const std::string ch ) { unsigned int x,n=0; std::string str; do{ x=0; if(n+2<ch.size()) memcpy(&x,&ch[n],3); else if(n+1<ch.size()) memcpy(&x,&ch[n],2); else memcpy(&x,&ch[n],1); n+=3; for(int i=0; i<4; i++) { str+=enc64code[x%64]; x/=64; } }while(n<ch.size()); return str; } std::string base64deckai(const std::string ch ) { static std::string inv; static flg=0; unsigned int x,n=0,i; if(!flg) { inv.resize(128); for(i=0;i<enc64code.size();i++) inv[enc64code[i]]=(char)i; } std::string str; do { x=0; for(i=0; i<4 ; i++) x+=inv[ch[n+i]]<<(6*i); n+=4; i=str.size(); str.resize(i+3); memcpy(&str[i],&x,3); }while(n<ch.size()); return str; } int main(){ std::string a="C++に関する質問やら話題やらはこちらへどうぞ。"; std::string b=base64enckai(a);std::string c=base64deckai(b);std::string d=base64enckai(c); std::cout<<"moto a=\""<<a<<"\"\n"<<"test b=enc(a); c=dec(b); d=enc(c);\n"; std::cout<<"a==c? "<<(a==c?"True":"False")<<"\n"; std::cout<<"b==d? "<<(b==d?"True":"False")<<"\n"; }
790 :
709 :2011/04/19(火) 14:09:29.72
Info-Zipか7-zipに直にアクセスしたいのですが。やり方わかりますか? ソース落として動かそうとしたらわかりませんでした。
>>784 は同じ書庫を何度もオープンしていたからでした。
下位の書庫の存在確認のために、上位から順に開いていって確かめてました。
格納ファイル情報もキャッシュしたら解消できました。
793 :
デフォルトの名無しさん :2011/04/20(水) 10:41:25.67
QACのような性的解析ツールで無料で使えるもので おすすめはなにがありますか? NULLポインタアクセスとメモリリーク検知が出来れば あとはまあどうでもいいです。
ぼくも性的アクセスしたいです!
struct Boo{}; int buf[64]; Boo* b = new(buf) Boo[3]; とやると buf[0]に3が入ったり入らなかったりするんですがどういう規定があるんでしょうか。
>>795 よくある実装では、 Boo に対してデストラクタ呼び出しが必要かどうかで変わる。
その場合 3 が入ってるかどうかと static_cast<void*>(b) != &buf[0] が連動してるはず。
メモリリークはvisualC++つかえよ。普段使って無くても、検査の時だけつかえよ。簡単。
>>799 ちょっwww、どうやってVCで検査すんお!??
#include <crtdbg.h>
BorlandC++にもcrtdbg.hは存在していてた。しかしMFC 、 ATL.が存在してないから(メモリーリーク検出の)機能はしないと思われる。 BCC、crtdbg.hの中身。 Borland version of Microsoft CRTDBG.H header file This is used by MFC and ATL.
おまいら、性的解析を動的解析とごっちゃにしていないか? >793が欲しいのは性的解析ツールだぞ。
>>801-804 ありがと〜、おまえら優しすぎて涙が出てきた。
いままで自作のアロケーター作ってそこに開放し忘れ機能しこんでたお。
visualC++にも静的解析ついた気がするな。 コンパイルに出来た気が。 解析に時間かかりすぎて使ったことはないが。
>>807 /analyze スイッチか
vcユーザーにとっては一番手軽だな
811 :
793 :2011/04/20(水) 16:56:01.66
>>798 気に入った! 家に来て妹のコードを性的解析していいぞ
可変個の引数関数
fnc("aaa","vvv"); と使う。
*#define fnc(...) fnc_(__VA_ARGS__,NULL)
int fnc_(char *p, ...){
va_list L;
va_start(L, p);
L = (char *)L - sizeof(char*);
char *ch;
while((ch=va_arg(L, char*))!=0)
printf("%s\n",ch);
va_end(L);
}
http://ameblo.jp/cpp-prg/entry-10151372280.html
>>812 C++0xに対応したコンパイラを使えば、無駄なことをしなくてもそのまま使える。
>>812 なんでわざわざそれ用に PP が用意してる ENUM_PARAMS とか ENUM_BINARY_PARAMS とか使わずに自前で書くの?
1から100の連番を64bit数に関連づけるなら配列が良いと思いますが。 1から1億の連番ならどうすればいいですか? 省メモリで速度が速いのが良いです。
ヒープ
818 :
816 :2011/04/22(金) 09:59:57.10
すみません。常に1億個存在するわけではなく最大で一億でした。 1から一億のうちの10%=1000万個程度が出現します。 配列を使う場合の容量はこうです。 8バイト * 一億個 / 2^20 = 763メガバイト。
要は、大抵は80MB程度で最大763MBか。そのくらいなら普通に配列でもいいんじゃね?w あー、速度も必要か。どういう速度が必要かによって、vector/deque/map/list好きなの使えばいいんでね?
>>816 ,818
struct pair { int_least32_t key; int_least64_t value; };
std::vector<pair> v;
で、 v を常にソート済みに保つ。
sizeof(pair) は典型的には 16 バイトか 12 バイトになると思う。
その場合の容量はこう。
16バイト * 1000万個 / 2^20 = 153メガバイト。
ただしキーで参照するのは O(logN) で、追加削除は O(N) になってしまう。
(配列の場合はいずれも O(1) )
std::map にすれば追加削除も O(logN) に抑えられるけど、メモリ使用量は
たぶん数倍に増えてしまう。
821 :
816 :2011/04/22(金) 10:26:04.37
場合によってはunordered_mapがいいかもね
template<class iterator, class returntype=typename iterator_traits<iterator>::typename> returntype func(){ return 1; } この関数の戻り値の型をイテレーターの型を指定しないでfunc<int>();見たいに呼び出す方法教えてください。
>>823 それじゃ iterator の型が定まらないので無理。
定まるとして考えてみてください。
定まると仮定すると問題自体が成り立たないように見える。
>>820 こうなると64bitEXEも実用的になってくるな
しかしCPU自体の速度はさほど向上してないし、STLはマルチコアに対応して
ないしでちょっと苦しいな
>>826 第一引数にiteratorの引数を持ち、呼び出すときfunction<int>(iterator)と仮定すればなりたつだろ。
一つのソースコードを、#define(UNICODEなど)指示を変更しながら 自動で複数回ビルドして異なるEXE作る方法ありますか?
自己解決しました /D (プリプロセッサの定義) CL /DDEBUG TEST.C 次のコマンド ラインでは、最初のソース ファイルと同じ名前の実行可能ファイルが C:\BIN に生成されます。 CL /FeC:\BIN\ *.C
>>830 大文字で書かれるとすごい違和感。VMSとかCP/Mとか思い出しちゃう。
833 :
デフォルトの名無しさん :2011/04/23(土) 07:36:07.06
>>823 既定のテンプレートの引数を関数テンプレートで使えるの?
func<int>() って第一のテンプレート型実引数イテレーター
の型を指定していることにならないの?
(ポイントがズレてたらごめん)
初級者「C++全然わからんw」 中級者「C++全然わからんw」 上級者「C++全然わからんw」 標準化委員会「C++全然わからんw」 顧客「C++分かるよね?」 営業「もちろんです!!」
ついったーネタを転載とはやはり天才・・・
ニュー速じゃね? 初級者「C++全然わからんw」 中級者「C++全然わからんwwww」 上級者「C++全然わからんwwwwwwwwwポゲwwwwww」 標準化委員会「C++wwwww全wwwww然wwwwwwwwわwwwwかwwwらwwwんwwwwwwwwww」
文字列配列について質問があります。 g++4.4.5では以下のソースはコンパイルできます。 #include <string> int main(int argc, char *argv[]) { std::string foo[argc+10]; } VCでは配列確保に定数式が求められるため、コンパイルできません。 #include "stdafx.h" #include <string> int _tmain(int argc, _TCHAR* argv[]) { std::string foo[argc+10]; } これは、どちらの挙動がより標準に準拠しているのでしょうか?
コンパイラがどの規格に準拠しているかぐらい、自分で確認しろよ。
>>837 それgccの独自拡張だから
-ansiつけてコンパイルしてみな
HDD内のファイルリスト、URLリストを保存したいのですが、次の条件があります。 ・ メモリの占有量が小さい(これを一番重視) ・ 各ファイル(URL)は固有番号をもち、番号からパスを返す関数がある。 これはどのように実現したらいいですか。
SQLiteでフルパス、番号をそのまま格納するってことですか? ディレクトリ名だけ記録してツリー構造にしたらメモリ減らせると思うのですが。 しかしこれだと、ディスクへ記録するのと、逆引きの方法がわからないです。
SQLiteでDBファイルを指定すれば、好きな場所に保存できるだろう 抽出したければ条件を指定すればいいだけだし、 いったい何が疑問なのかさっぱり分からない
>>844 俺はやっぱりSQLiteをおすすめするけど自分でやりたいなら
データ挿入の仕方はBツリーとかB+ツリーでググればソース見つかるはず
逆引きは文字列ハッシュ値保存すればできると思うけど
効率的な管理方法は俺には分からないわ・・・
ありがとうございます。 SQLiteでデータベース作って、サイズや速度に問題あったらまた聞きに来ます。
mapの速度。Google遅いかメモリ食い過ぎ。 stlport_std::hash_map Insert Time: 8.859 sec. Search Time: 2.875 sec. ページフォールト数: 11007 最大ワーキングセットサイズ: 42045.4KB stlport_std::tr1::unordered_map Insert Time: 9 sec. Search Time: 2.765 sec. ページフォールト数: 11007 最大ワーキングセットサイズ: 42045.4KB stlport_std::map Insert Time: 12.265 sec. Search Time: 14.953 sec. ページフォールト数: 11422 最大ワーキングセットサイズ: 46846.0KB google::sparse_hash_map ver.1.10 Insert Time: 65.171 sec. Search Time: 11.563 sec. ページフォールト数: 12004 最大ワーキングセットサイズ: 48631.8KB google::dense_hash_map ver.1.10 Insert Time: 11.89 sec. Search Time: 5.906 sec. ページフォールト数: 29674 最大ワーキングセットサイズ: 82579.5KB stdext::hash_map Insert Time: 10.109 sec. Search Time: 7.5 sec. ページフォールト数: 13922 最大ワーキングセットサイズ: 56836.1KB tr1::unordered_map Insert Time: 11.796 sec. Search Time: 8.641 sec. ページフォールト数: 13922 最大ワーキングセットサイズ: 56836.1KB std::map Insert Time: 14.078 sec. Search Time: 13.953 sec. ページフォールト数: 14323 最大ワーキングセットサイズ: 58740.7KB
set速度 stlport_std::hash_set Insert Time: 7.812 sec. Search Time: 2.844 sec. ページフォールト数: 11008 最大ワーキングセットサイズ: 42033.2KB stlport_std::tr1::unordered_set Insert Time: 7.515 sec. Search Time: 2.922 sec. ページフォールト数: 11008 最大ワーキングセットサイズ: 42033.2KB stlport_std::set Insert Time: 9.89 sec. Search Time: 13.75 sec. ページフォールト数: 10446 最大ワーキングセットサイズ: 42844.2KB google::sparse_hash_set Insert Time: 54.656 sec. Search Time: 10.859 sec. ページフォールト数: 11428 最大ワーキングセットサイズ: 46583.8KB google::dense_hash_set Insert Time: 10.953 sec. Search Time: 5.922 sec. ページフォールト数: 27480 最大ワーキングセットサイズ: 76283.9KB stdext::hash_set Insert Time: 9.984 sec. Search Time: 6.297 sec. ページフォールト数: 13923 最大ワーキングセットサイズ: 56840.2KB tr1::unordered_set Insert Time: 15.218 sec. Search Time: 8.578 sec. ページフォールト数: 13923 最大ワーキングセットサイズ: 56840.2KB std::set Insert Time: 11.484 sec. Search Time: 12.172 sec. ページフォールト数: 14323 最大ワーキングセットサイズ: 58740.7KB
初心者なんだが データ型 配列名[][横方向の要素数] = { { [0][0]の初期値, [0][1]の初期値, ・・・ }, { [1][0]の初期値, [1][1]の初期値, ・・・ }, { [2][0]の初期値, [2][1]の初期値, ・・・ }, : }; こういう配列の代入って初期化の時しかできないの? もしそうだったら、初期化じゃなくてもこう代入する方法はない?
std::initializer_listを待つしかないな
>>853 よくわからんがそうなのか
とりあえず宣言した時じゃなくて、その後に上記の様に代入する方法を知りたい
>>854 そのように初期化した配列を用意し、目的の配列にコピーする。
>>854 C#にはそういう書式があるが、C/C++にはない
C++0xには付くかもね
>>857 ↓みたいに書いてもいいと思うよ。別に読みずらくないし大してカッコ悪くもない
配列名[0][0]=初期値; 配列名[0][1]=初期値;
配列名[1][0]=初期値; 配列名[1][1]=初期値;
initializer_list 早く使えるようになってほしいな… static int a[] = { 1,2,3,4,5 }; std::vector<int> v( a, a+sizeof(a)/sizeof(int) ); とか書くの煩わしい
860 :
デフォルトの名無しさん :2011/04/24(日) 11:34:12.42
template< typename C > class A { public: typedef typename C::value_type value_type; }; class B : public A< B > { public: typedef unsigned int value_type; }; これをVC++2010EEでコンパイルすると error C2039: 'value_type' : 'B' のメンバーではありません。 とエラーになります。どうすればコンパイルが通るようになりますか?
Bが確定しないのに、Bを含むAをBが継承するって、 どれだけ無限に再帰させれば気が済むんだよ?
class A { void func() { B* a = new B; } }; class B { //なんたらかんたら }; とするとBが定義されていないってエラーが出ます。前方宣言もだめでした。 この場合BをAの前に持って行きたくない時はどうすればいいですか?
無理だからあきらめろ
先行宣言で使えるのはメンバ変数とか引数とか、具体的なクラス構造を 参照する必要がない場合だけで、インスタンス作っちゃうとアウト。
>>862 class B の「宣言」をヘッダーでしてそれをインクルードしろ
これは定石
ついでにclass A もヘッダーで宣言しておけばよい
要するに宣言と定義を分ければOK
int hoge[100]; // 略 std::sort(&hoge[0], &hoge[100]); STLのsort等で、上のように普通の配列を使う事は可能ですか? VC++で動作することは確認したのですが、保障されているんでしょうか。
>>866 ポインタはランダムアクセスイテレータの要件を満たすので多分OKだと思う
&hoge[100]っていいんだっけ?
>>868 問題ない。
std::vector の &v[v.size()] はダメだけどね。
int hoge[100]; std::sort(hoge,hoge+100); 個人的にのが好き
普通は std::array でしょう
872 :
860 :2011/04/24(日) 17:49:01.38
>>861 別に再帰は起こらないと思いますが。
大体再帰がオーバーフローするなら、
そういうエラーになるでしょ?
874 :
デフォルトの名無しさん :2011/04/24(日) 18:36:20.27
A を具現する時点ではまだ B が不完全型なので C はメンバを持たず、よって検索に失敗する つまり無理
BCCのほうがわかりやすいメッセージ吐くな 依存関係にある型限定子 'B' に 'value_type' という名前のメンバー型がない
>861 その構図だけなら CRTP として良く使われる技法だけどね。
>>862 です。皆様ありがとうございます。出掛けていて返事が遅れました。
宣言をヘッダーに置き、定義をソースファイルに置く事により無事解決しました。
ただ一つハテナ?と思う事がありました。
コンストラクタ内でnewしてしまうと、永久再帰に飛び込んでしまい、スタックオーバーフロー
で落ちます。それでinit()という別の初期化メンバ関数を作ったのですがどうにも不格好です。
#ifndef CLASS1_H
#define CLASS1_H
class B;
class A {
B* b;
public:
A();
void init();
void print() const;
void print2() const;
~A();
};
class B {
A* a;
public:
B();
void init();
void print() const;
void print2() const;
~B();
};
#endif
#include <iostream> #include "class1.h" A::A() : b(0) {} void A::init() { b = new B; } void A::print() const { std::cout << "This is class A." << std::endl; } void A::print2() const { b->print(); } A::~A() { delete b; } B::B() : a(0) {} void B::init() { a = new A; } void B::print() const { std::cout << "This is class B." << std::endl; } void B::print2() const { a->print(); } B::~B() { delete a; } int main() { A a; B b; a.init(); // コンストラクタに入れると永久ループになりスタックオーバーフローする b.init(); // 同上 a.print(); b.print(); a.print2(); b.print2(); }
何とかnewをコンストラクタに入れてすっきりさせてしかも永久再帰にならないように するスマートな方法はないでしょうか?
クラスA,Bの結びつきがそこまで強いなら 元からAとBを合わせたほうがすっきりするような気がするけど…
A,Bをメンバに持つクラスを作ってコンストラクタでそれぞれのアドレスを渡す
>>880 やっぱりそうですね。
>>881 コンポジションですね。これでようやくコンポジションの使い方が分かりました。
うっかり継承を使って問題を複雑にする所でした。
本当にコンポジションで済むなら A、Bに引数付きのコンストラクタ作っって、 デフォルトコンストラクタからnewするときにthisを渡せばいいんじゃないの? そもそも、再起がどうでコンパイルエラーをなくす事に気を取られて、 自分の動かそうとしているコードの意味を理解していないんじゃないか? あと、相互参照してるときにデストラクタで相手を保持してるポインタを直接deleteすると、実行時に死ぬよ。
>>883 今回はコンポジションが最適なようです。
プログラムを組み直します。
>そもそも、再起がどうでコンパイルエラーをなくす事に気を取られて、
>自分の動かそうとしているコードの意味を理解していないんじゃないか?
確かにご指摘の通りでした。
相互参照はしてないので、この場合は大丈夫なのかな?
boost::weak_ptrがわざわざ用意されているのも、boost::shared_ptrで 循環参照の環が切れなくなってリソースが解放出来なくなるトラブルを 防ぐためでしたね。 頭で理解しているのと、実際にプログラムを組んでみるのとではかなり 差があります。こういう差を持っているとデバッグの時に苦しみそうです。
2つのbool型変数a,bがあるとき、 if(a==b) funcA(); else funcB(); これを少しでも高速にする方法ってありますかね xorのほうが速かったりしますかね?
>>886 本当にそんな箇所がボトルネックなのか?
もっと他に高速化すべき箇所があるんじゃないか?
別にネックじゃないけど高速化したいんじゃないの?
必要性なんぞこの質問に関係ないだろ
890 :
886 :2011/04/29(金) 18:38:14.98
>>887 一回一回はそれなりに軽快なんだけども、この分岐を相当数経由するので・・・
今後のためにも、boolの高速な比較方法を教えていただきたい
引数と返り値をあわせられるなら関数ポインタ使うとか void (*func)() = funcB; if(a==b) func = funcA; func(); または func = a==b ? funcA : funcB; func(); elseない分ちょっと速いかも。 あとは邪道かもしれんが配列にして void (*func[])() = {funcB, funcA}; func[a==b](); くらいかな
>>891 関数ポインタか、なるほど。試してみます。
全部のヤツで「a==b」を使って比較しているようですが、
==が一番高速ってことなのでしょうか。
個人的にはa^b(exor,ビット演算)のほうが速いと思っていたのですが。
速いかどうかは測ってみるのが一番
ビット演算子の方が速いよ 心配ならいろんなところググって調べろ
分岐ってそんなに差が出るものなの?
たとえ0.1秒の差でも1万回通れば1000秒だ
0.1秒も差がつくわけねーだろ
>>892 if(a == b)の場合
> movzbl -1(%ebp), %edx
> movzbl -2(%ebp), %eax
> cmpl %eax, %edx
> jne L11
if(a ^ b)の場合
> movzbl -1(%ebp), %edx
> movzbl -2(%ebp), %eax
> cmpl %eax, %edx
> je L11
g++で比較してみたけど、マシン語レベルではどっちもほぼ同じだよ。
そもそも==で分岐などしない 比較結果のフラグレジスタの値を返すだけ 分かっていない奴は最低限アセンブラぐらいやってから語れよ
>>899 フラグレジスタを使って「ジャンプ(≒分岐)」する、と俺は習ったが。
そもそも==が分岐とは誰も言ってないぞ・・・
書き込み読んでから、な。
何故かx86限定っぼいけど、ビットxorしたからって分岐を無くせる訳じゃないから大差ないよ。 要は、殆ど無駄な努力。
==はただの演算子でしかない。 結果が返されるだけでジャンプや分岐とは無関係。
寧ろfuncA()やfuncB()をインライン展開できるように調整するとか分岐そのものをループ外に追い出すとか。
904 :
892 :2011/04/29(金) 20:54:19.26
>>898 わざわざありがとうございます。
これで安心して先に進めます。
関数ポインタ使ったら処理時間が短くなりました。
皆さんありがとうございました。
>>904 最後になんのプログラムなのか教えて
気になるよ・・・
関数ポインタって分岐予測もプリフェッチも全部フラッシュしちゃうんでしょ? C++の仮想関数のコストが騒がれたのも同様の理由による パイプラインが深い今のCPUにとってはかなりの重荷
みひく
関数ポインタは確実に遅くなる。 分岐予測など効かず、速度を出す場面で使うべきで無い。 コンパイラ、CPUにもよるが、単なる関数呼び出しやGOTOよりも遅い。
>>904 はベンチとって速くなったっていってるんじゃないの?
>>905 画像処理系のプログラムです。
お世話になりました。
>>909 はい、関数ポインタも含めていろいろといじくったら、ベンチの結果が改善しました。
逆に悪化したところもあると思うので、そこらへんは明日やろうと思います。
皆さん本当にありがとうございました。
へえ、やっぱ速くなったんだ 分岐が大量にあったり多岐にわたるコードなら、関数ポインタもいまだ有効とは聞くが。 分岐予測だのあまり過信せず、パフォーマンスを一々計ったほうがよさそうかな?
関数ポインタを使った積もりでも、巧いこと閉じてさえいればコンパイラによってはインライン展開できるだろ。
速くなったのは他の所をいじくったせいじゃないの?
>>906 たしか飛び先が前回と同じなら大丈夫だったと思うよ
まぁ何のために関数ポインタって飛び先が変わるためだろうからあんまり意味ないんだろうけど
関数ポインタを使って関数呼び出すと、インライン展開は確実に出来ないのはわかるだろ。 if文で関数呼び出したときは、インライン展開される可能性はある。 スイッチ文もあまりはやくならない。 if文で確定しやすい順に判定するのが一番。
どうコンパイルされてるか分からんのであれだが、 > func = a==b ? funcA : funcB; > func(); > > elseない分ちょっと速いかも。 これはelse無いと判断していいんだろうか。
60%、10%、1%、1%、1%、1%、・・・などと分岐に偏りがあればこの順に判定。 1%、1%、1%、1%、・・・、10%、60%とすると無駄な判定が増える。
>>915 でもインラインが必ずしも速くなるわけじゃないからな
キャッシュミス起こしたり変数大量にあるとレジスタ足りなくなったり
ってWikiにあったぞ
プロファイラがあれば取って見ればどの関数がスピードアップしたのか一目瞭然
>>911 実測に重きを置くのは賛同だけど基本的に
>>887 でFA
組み込み向けで特定の(たった一つの)機種のために最適化するなら何でもありだけど、
ある程度動作対象マシンに幅のある汎用プログラム書いてるならバイナリレベルの最適化は時間の無駄だと思う。
だから必要性なんぞ問題にしてない
問題は何だ
自己満足。つまり、自慰。 相手が満足するかは二の次と言う意味では、素人童貞は童貞と一緒と言うことだ。
画像処理なら大量の分岐を無くす事は意味あるかもなぁ
前にほんのちょいとだけC言語をかじったものですが またプログラミングっぽいことがしたいなと思い始めてきました C++はプログラム言語の中でも取得が難しいとか聞きますが、 ほぼ未経験の状態で勉強を始めるのは無謀でしょうか
Cの基本ができてれば、できなくは無いな。 クラスは必要なら使えばいい。でもテンプレート関係は使うとかなり楽しいよ。
べつにそんなことはない
誰でも最初は未経験だよ
C++は入門書に加えて最低でもEC++とMEC++ぐらいは理解してくれてないとバグ混入やパフォーマンス低下が怖くて現場では使えない
いらない解説どうも
>>925 いきなりCプラプラはまず無理だからPerlとか人気で楽で使える言語先にやって慣れてからにしたほうがいいよ
>>929 自分に関連するコードの差分チェックすらしない人なの?
>>925 最終的に何を作りたいかで、言語は選ぶのがいいと思うよ
特にやりたい事が楽にできるライブラリがあるかは、結構ポイントだと思う
C++は気に食わない所があったら、直せなければ気が済まないような人に向いてるかなw
今ならC#とか結構いいんじゃないか
.net入ってるなら、コンパイラも入っている筈だし
C#のことは聞いてないだろ
底辺ドカタは人とのコミュニケーション能力ないからドカタになるんだろ ITドカタの場合はコンペータとしかコミュできないからしょうがないよな ドカタは人とのコミュであさっての方向レスをシャキーーンとするからな
それはC++に関する質問ですか?
自己紹介だろ
あなたはC++とだけしかやり取りできないですか?
何を言っているのですか。Cとも出来ます。
C++で、幾つかのデザインパターンを使って、クラスを継承させながら モジュールを作れるようになったら、もう中級レベルを名乗ってOkですか? C++初めて3ヶ月位ですが、何か目標みたいなのを探しています。
中級レベルを名乗るならEffective C++とExceptional C++の内容が最低限分かってないと駄目じゃね デザインパターンとか初級者レベルだべ
あとEffectiveSTLあたりのSTL関連が理解出来て初心者卒業じゃね?
>>940 boostのラムダあたりが実装できるレベルが中級
なんか似たようなのTwitterで見たなw これをパッと的確に答えられると中級者らしい >「boost::shared_ptr の実装は非常に非効率で,私はあれはポリシー化すべきだと思うのですが,これについてあなたはどう思いますか?」 >「boost::shared_ptr か boost::intrusive_ptr かのどちらかを人に勧める場合,デフォルトではどちらが良いと思いますか? 理由を添えてお答えください.」 >「boost::weak_ptr の有効な使い方を1つ挙げてみてください.」
STLはそこそこ使えるけど、まともに何かを作ってないのでデザインパターンとかさっぱり
boost使わないと中級者になれないのか
今って勉強するのに時期が悪いんだよなぁ。 本買ってもC++0xに準拠してない。STLとかがらっと変わるだろうし 早いとこ仕様固まって欲しい。
boost で使われている C++ の技術を理解できればよい boost そのものは使わない・使えなくても
レスどうもです!中級になるのも一苦労みたいっすね とりあえず上の三冊を揃えて、勉強します どうせGW何もすることないし
桃栗3年柿8年
中級者になれなくてもライブラリ使って何か組めるようになったんならいいじゃん!
BoostかC++0x使わないC++なんて使いもんにならねーだろjk
中級者を名乗っても別にいいと思う。 いつまでたっても上級者と名乗る自信をもつことはないのだから。
>926-933 多くのレスをどうも有難うございます 一応アクションゲームっぽいのが作ってみたいかな…と思って調べると やっぱりCとかC++が有用そうで、こちらで質問させて頂いた次第です なんとかなるというお話と無理というお話で解れているみたいなのでちょっと迷いますが、 とりあえず少し弄ってみて、無理そうだったらC#でも改めて調べてみる事にします
GUIのプロトタイピングするんであればC#お勧めだな。C#標準でGUI関係を内包してるからね。 速度とか複雑な描画とかが必要になったらそのときにはDirectX関連かOpenGL関連にすすむといい。
>>956 じゃあ何だというのです
エラーになる理由が見当たらない
どうやったら上級者?
C++でC++のコンパイラ実装したらかねぇ??
標準化委員会ですらよくわかっていないんだから名乗れば上級者
>>951-952 ,956,960
プログラムの意味的にはそこでコピーコンストラクタを要求するが、
コンパイル結果としてコピーコンストラクタを呼び出す必要は無い、
という少し特殊な状況です。
>>964 テンポラリのconst参照による束縛は仕様的にはコピーだったということですか?
だから普段は最適化でコピーは呼ばれないように錯覚してたけど
今回はシグネチャレベルで弾かれて驚いたと
>>965 const参照による束縛は関係ありません。
初期化の構文と、その解釈と、その後の最適化の話です。
>>966 これのことかな?
「コンストラクタに無名のインスタンスが渡されたらコピーコンストラクタは呼ばれない」
規格書 8.5.3 If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined): <--- コピーされるかどうかは実装依存 - The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object. - A temporary of type “cv1 T2” is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary. The constructor that would be used to make the copy shall be callable whether or not the copy is actually done. <--- コピーされようがされまいが、コピー可能でなければならない エラーになるのはこのためとおもわれ
省略してもよいと決められていても省略しない場合に禁止されていることは出来ない
externって普段使ってますか? どういうときに使いますか
>>968 8.5.3 は参照の初期化だからこの流れとは違うね。
8.5 p14 にある "If the destination type is a (possibly cv-qualified) class type:" の
↓ここが該当する。
> If the initialization is direct-initialization, or if it is copy-initialization where the
> cv-unqualified version of the source type is the same class as, or a derived class of,
> the class of the destination, constructors are considered. ...
この場合のコピーコンストラクタの省略については 12.8 p14,15 にある。
ん?8.5 p14には - If the destination type is a reference type, see 8.5.3. とあるけど 参照の話ではないの?
974 :
972 :2011/05/02(月) 14:30:38.71
>>971 ほかで宣言されたグローバル変数を使いたいとき
色んなライブラリで結構使われてませんか?
externの意義がよくわからん includeすれば使えるんじゃないの? C++から始めたからか、よく分からん
グローバル変数を複数のソースファイルに渡すのに使えるぞ
static int manko; extern int manko; こうやって他人に嫌がらせするのに使う。
名前空間ですよね
char A,B,C,D,Eを99個持つとしたときにどっちの方が効率がいいのかな 1:構造体を99個作ってcharメンバを5つ持つ 2:コンテナ<コンテナ<char>>にして持つ
983 :
デフォルトの名無しさん :2011/05/02(月) 23:24:50.63
3: だね
効率的にも意味的にも1に決まってる。 効率なんてどうでもいいと思うが
>>984 ですよねー
なぜあの時構造体が思いつかなかったのか・・・
何故コンテナで持つことを考え付いてしまったのか
まぁどうせC++なんだからさ。ケチケチしないでコンテナ使っていくのはある種正解。
char a[99], b[99], c[99], d[99], e[99];
std::array<std::tuple<char, char, char, char, char>, 99>
typedef std::pair<std::string, char> StringCharPair; std::map<std::string, char> hoge[99]; hoge[0].insert(StringCharPair("A", '0')); hoge[0].insert(StringCharPair("B", '1')); hoge[0].insert(StringCharPair("C", '2')); hoge[0].insert(StringCharPair("D", '3')); hoge[0].insert(StringCharPair("E", '4'));
派生クラスで外部の基本クラスのprotectedメンバにアクセスしたいばあいってどうするのよ class Base { protected: int hoge; }; class Derived { public: void f(Base * pBase) { ... pBase->hoge ... // エラー } void f(Derived * pDerived) { ... pDerived->hoge ... // 問題ない } };
friendでおk
>>987 は thread_info inf[MAX]; を int tid[MAX]; HANDLE ht[MAX]; int stat[MAX];と書くバカ。
>>988 は int cur_count, count_limit, thread_id; をint num[3]; とか書くバカ。
>>989 は int cur_count, count_limit, thread_id; をpair<string, int> num; とか書くバカ。
>>990 は #define private publicとか書くバカ。
こういう奴らが他人が読めない糞コードを量産する。
protectedなんだからしょうがないだろ。実体がDerivedじゃないかも 知れないのにDerivedに見せるのはおかしい。 実体がDerivedとわかってるなら、 derived *pd = dynamic_cast<derived *>(pb); 実体がDerivedじゃなくても公開したいなら、Baseに static int &get_hoge(base *pb) { return pb->hoge; } でも作るのかなあ。
>>994 だけど必要になってしまったんだ
> 実体がDerivedじゃなくても公開したいなら、Baseに
> static int &get_hoge(base *pb) { return pb->hoge; }
> でも作るのかなあ。
なるほど、これで回避できるのか・・・
>>995 なんで Derived って名前で Base を継承してないの?
>>992 はSoA vs AoSと言う議論も知らない馬鹿w
>>996 書き忘れてただけ
誤: class Derived
正: class Derived : public Base
>>992 キャッシュ効率を考えてあえてバラして配列にすることはあるでしょ
随分と頭がカッチカチだなぁ・・・
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。