基本のリンクは少し更新しといた。あと Libraries のリンクを復活させといた。 後は好きにして。
8 :
デフォルトの名無しさん :2010/02/13(土) 23:48:06
前スレの話だけど、関数テンプレートならinline付けずに ヘッダに定義書いても全然問題ないことをどっちか片方が知らないように感じた。 俺の誤解だといいんだけど。
>>9 さすがにそれは無いでしょ。それだと判断基準以前の話になってるはず。
前スレの方が上とはけしからん age
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
ところで現在のC++0xは いつ頃 正式なC++になるんですか?
2011年10月23日2時13分25秒頃
VS2010はSP1で完全対応してくれるんかいな
if else文で文字列のパターンを32個 チェックするのが、どうにも気持ち悪いのですが 何か別の方法はないでしょうか?
関数ポインタとの連想配列作るとか
パターンを配列に入れてループ
20 :
◆GWRSHcLrd6 :2010/02/14(日) 19:18:15
どうも。 スマートポインタにメモリプールを実装してみました。 (なんか保守的GCみないな感じになりましたが・・・) まだうpしてませんが(随分汚いので)、ベンチだけ取ってみました。
で、ベンチは?
ループは10000, サンプリングは5で行いました。 boost::shared_ptrのベンチマーク(非スレッドセーフ) 単純な生成ループ: 15, 空ポインタに代入: 12 オブジェクトのリセット: 25, オブジェクトのコピー: 24 オブジェクトの解放: 9 framework::smart_ptrのベンチマーク(with メモリプール) 単純な生成ループ: 3, 空ポインタに代入: 12 オブジェクトのリセット: 12, オブジェクトのコピー: 12 オブジェクトの解放: 6 トータルスコア: boost::shared_ptr: 85 framework::smart_ptr: 45 boost::shared_ptrに対する性能 単純な生成ループ: 500.0% 空ポインタに代入: 100.0% オブジェクトのリセット: 208.3% オブジェクトのコピー: 200.0% オブジェクトの解放: 150.0% 全体: 188.9% いやあ、劇的ですわ ソースが汚いので、奇麗に書きなおせばあと10%はアップすると思います。
既存の実用アプリでレポ
まずはスマポのソースうp
C++ではメソッドチェーンを、あんまり使わないんだね
>>25 多用されてるでしょ。主にoperator系、特にストリーム操作とか。
印象は違うかもしれないけどオブジェクトのメソッドがオブジェクト自身を返して連鎖していくって意味では
まさにメソッドチェーン。
>>27 このスマポってライセンス何なの?
まだ考えてない?
ま、まだ考えてないです・・・ ライセンスは何がいいんでしょう・・・?
ただの習作でしょ。 実用プログラムに組み込みたいと思ってる奴なんて要るの?
Googleのメモリ管理でいい。tcmallocとかいうやつ
アロケートしたメモリのバイト数分だけジェリービーンズで支払う
まだソース見ないから分からないけど NYSLライクなら昔作ったスレッドセーフ用のスマポと比較して 性能が良かったら使おうと思った ライブラリに合わせて改変することになるだろうからLGPLとかだと無理なんだけど この先も色々評価して高速化するなら需要はあるんじゃね?
>>27 こんなの遅くて使いものにならんでしょ。
以下の問いに対して、少なくともdlmallocよりも高効率なのかよw?
こんな糞データ構造で、メモリの空き領域をどうやって効率的にさがせる
のか答えてみろよw?これじゃ単なる線形リストだろw
このスレに2度と来るないいな?わかったか?
>>30 >>33 まあ、これから頑張って独自性がでるようになってきたら、
ライセンスをつけたいと思います。
それまでは改変自由で(まだ大したものじゃないですしね)。
>>31 tcmalloc、ググりました。
こういうアロケートの仕方もあるんですね。
でもあれってアロケートはシステムコールとかで
バリバリにコーディングされているのかな?
ちょっとコード見てきます。
速度はたいした問題でない。既にある物より圧倒的に遅いなら別だが。 安定していて使いやすいこと。 しかしGoogleのメモリ管理もあまり流行ってないし、普及させられるほどの価値ある物は出来ないと思う。 メモリプールしても全体の速度向上はほとんど望めない。 普及させられるとしたら、boost互換のインターフェースでboostよりメリットがあること。
>>36 メモリ操作のみなら、Googleのメモリ管理は超速だが
実際にアプリに組み込むと何の変化も出ない。
現実アプリはメモリの生成・解放ばかりしていない。
プールはおまけにするか、Google任せにしてスマートポインタ開発のほうが
需要出ると思う。
Googleはこんなこともしてたのか知らんかった。 ちょっと見てみたけどtcmallocって改良版dlmallocみたいなのか。
>>27 線形以外の探索ってどんなのがいいのかねぇ
>>27 このプールから削除する場合はどうなるんだ?使い捨て?
>>42 最速の固定長の小メモリブロックアロケータは simple segregated storage だとわかりきっている。
探索しないでいい。
ヒープメモリーにヒープ構造を!w
boost::shared_ptrにもメモリプールを使うオプションがあったような
>>43 inner_ptrの方でゼロ初期化され、新たなアロケートで再利用されます。
というかカウント0のものはゴミとみなして新しくAllocした時にそれを使います。
で、ブロックが空、なおかつ、ブロックを多く確保しすぎている場合は
そのブロックはdeleteされて前後のブロックをリストで繋ぎます。
>>45 そうなんですよw
じぶんに考え。 N 十分大 char* p[0]・・・p[N] メモリブロック メモリの使用状態を1ビットで表す 00011100010101000000 連続領域が必要なら0の連続を選択。 はじめはp[i]はNULLにしておく。
2つアロケート ↓ 0001 ABCD 1234 5678, 0001 4321 DEDE 5678 ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ 解放 ↓ 0000 0000 0000 0000, 0001 4321 DEDE 5678 ~~~~~~~~~~~~~~~~~~~ アロケート(再利用) ↓ 0001 0123 2567 ABAB, 0001 4321 DEDE 5678 ~~~~~~~~~~~~~~~~~~~ アロケート(ブロック追加) ↓ ブロック2をnew 0001 0123 2567 ABAB, 0001 4321 DEDE 5678 0001 0CCC 1224 5555, 0000 0000 0000 0000 ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ 解放 ↓ 0001 0123 2567 ABAB, 0001 4321 DEDE 5678 0000 0000 0000 0000, 0000 0000 0000 0000 ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ 不必要と判断、ブロック2をdelete 0001 0123 2567 ABAB, 0001 4321 DEDE 5678
>>47 いったい何を目指しているの?
メモリブロック確保の速度なんて operator new の実装に任せておけばいいこと。
そんなところをがんばるよりも、他にすることは無いの?
って感じです。
カオス
>>50 すいません。高速化しようと思って少しそれてしまいました・・・
マルチスレッドでメモリ探索にロック掛けると速度落ちると思うから キューに入れて順番に処理すると良い思うが、キューへのアクセスにロックが必要 ロック無しにする方法ないか。
wait-free lock-freeのwikiみると、アトミック命令使えばロック無しのマルチスレッドできるらしいが。
operator new よりGoogleメモリ管理の方が高性能。
>>56 なら operator new を Google メモリ管理で置き換えればいいじゃない。
>>60 スマートポインタでLock-freeにするには? という話なのに、
Lock-freeを実現するために使用するスマートポインタの話をするのは順番が逆でしょう。
でも
>>60 のような用途に使える軽快なスマポは確かに欲しいけど。
RCUってなあに?
正直 マルチコア時代 を相手にするならスマポのコストが問題となることは 大抵ないと思うんだが。
で、依存無しのCASとかRCUとかはどう実装するんだ?
無理無理
通信系の処理プログラムを書いてるんですが 処理担当スレッドを作る場合、必要になったらbeginthread(もしくはbeginthreadex)で スレッドを起動して作業が終わったらおしまいとするのとスレッドプールをするのでは どちらがいいのでしょうか?
>>70 頻繁に起動終了を繰り返すようなものならスレッドプールが良いと思うよ。
スレッドの生成破棄もコストはあるからね。
getter/setterについて悩んでいます。 ●getterについて ・setterに対してgetterも用意されていたら、隠蔽になっていないのではないか? ・利用者がsetした時の情報を保持すればgetterはいらないのではないか? ●setterについて ・コンストラクタの引数で受け取る物は、setterも用意したくなるが同じ機能を2箇所に書いている感が? 書いたクラスが各メンバ変数に対してgetter/setterが存在する物になっていると、 無駄に手間をかけただけの構造体なんじゃないかと不安になります。 必要十分なgetter/setterを持つクラスを設計するには、どういう事を考えればいいのでしょうか?
>>72 >・setterに対してgetterも用意されていたら、隠蔽になっていないのではないか?
なんでそうなる
他にもいろんなprivate変数持ってる場合がほとんどだろ
>>73 「コンストラクタも含めて外部からget/setされないメンバ変数」を持たないクラスも多いです。
10個近くの設定値が必要なクラスとか、コードのうちgetter/setterが占める割合が多くなって、「なんだかなー」と思います。
そう思うなら思い切ってpublic変数にすればいいだろ でもgetter/setterを敢えて持つ理由は、プログラマに「今private変数を いじってますよ」という事を常に意識させる効果がある
>>72 class widget {
public:
inline void set_x(int _x) { x = _x; }
inline int get_x(void) { return x; }
private:
int x;
};
↓内部仕様を変更したくなった
class widget {
public:
inline void set_x(int _x) { p->set_x(_x); }
inline int get_x(void) { return p->get_x(); }
private:
impl *p;
};
しっかり隠蔽になってるね
基本的に公開する必要があるなら全部アクセサでいい
未来永劫仕様を変えない保証があるなら丸出しでもいい
コンストラクタの分だけセッターを作る必要はない
単純セッターなら普通は
void set(const Obj &obj) { m_obj = obj; }
hoge.set(Obj(a1, a2));
こうする
>>75 一貫性がないのは嫌なので、public変数にするとなると全てのクラスをpublic変数にする事になって、これも嫌な感じがします。
>>76 確かに隠蔽性がなくなるわけではありませんでした。
インターフェイスがすっきりしないのが嫌なところですね。
設定値が多い時は、構造体に纏めてget/setするという事ですね。
そのたくさんある変数はすべてset/getする必要があるの? 内部実装のためにあるデータだってあるでしょ 外部から見たときにset/getする必要があるやつだけ publicなsetter/getterを定義すればいいよ
vectorにクラスを入れるということは普通しないのでしょうか?
よくやる
むしろやらないでどうする
>>79 とても若干良くある
クラスのコピーコストが気になるレベルならポインタ格納するなりlist使うなりするけど。
>>60 明確な実装方法を表したサイトってないの?
クラスを入れる、っていう表現がまかり通るのが驚き。
#define class struct オヌヌメ
>>71 なるほど
ちなみにスレッドプールしておいたスレッドの空き/使用中の管理というのは自分でやる必要があるのでしょうか?
88 :
79 :2010/02/16(火) 18:25:17
よくやるんですね。ありがとうございます。 自分のプログラムで変なエラーが出てしまったので、もしかしたら間違ったやり方をしているのかと思いました。 できるんなら、何とかしてみます。
たぶんコピー、代入あたりで間違えてるんだろうな
pimplを勧める
#undef class
>>87 beginthread云々からWin32と仮定すると
IOCPに管理させるのが楽かもよ。
POSIXじゃないの?
おめーはpthreadも知らずWin32も知らないのか
誰に言ってるんだ?
誰が?
ワッフルワッフル
98 :
97 :2010/02/16(火) 22:23:48
誤爆しました。
え?
ww
うむ。苦しゅうない。
何の?
int get() { return mVal; } これよりも効率よくmValを外部に返す方法ってありますか?
>>72 まずインターフェースだけ考える。どんな変数を持ってるとかは敢えて考えないぐらいのつもりで、
とにかく利用者にとって自然な操作だけをメンバ関数(コンストラクタ含む)として列挙する。
それが済んでから、それらのメンバ関数を実装するための変数を必要なだけそろえる。
これなら「隠蔽になっていない」などという心配は起こりようが無いし、余計なコードも発生しない。
インターフェースを考える段階で、利用者から見て中にどんなデータが入っているのか
明らかでありメンバ関数呼び出しが煩雑なだけに見えるようなら、ただの構造体でいい。
>>104 #define get() mVal
foo.get();
110 :
◆GWRSHcLrd6 :2010/02/17(水) 07:22:13
>>103 あ、なんか僕が今作りなおしているやつも似た作りです。
これが効率よさそうですよね。
そういえばboostのsimple_segregated_storage(だっけ?)ってどういう仕組み何でしょうか?
>>109 なるほど。ちょいと見てみます
可変長引数パラメータて、使いどころがよくわからないんですが どういった時に使うんでしょうか? 同じようなことができるboostのfunctionもです。 掴み所を教えてください
>>111 可変長引数パラメータって何?
関数引数の ... のこと?
>>112 そうです。
使い方はわかるし、boostも使い方は理解できるんですが
何に使うのかがわからないんです。
特に後者のboostは、仮想関数の引数としてfunctionを利用しても
結局テンプレートだからオーバーロードになるわけですよね?
呼び出し側で型指定するわけですし、多態的に動作させるのもできないのでは?
ここで混乱している感じです。
>>113 printf() とか。
まぁ C++ では基本的に使わないな。
boost::function とは関係ないと思うけど、何のこと言ってんの?
>>114 返り値の型、引数の型を指定して関数ポインタを楽に生成できるじゃないですか。
このテクニックを利用して、引数の数、型が変化する処理を多態的にさせたいんです。
117 :
116 :2010/02/17(水) 11:55:42
付け加えておくと、
・可変長引数とboost::functionの使いどころは別である
・boost::functionは関数ポインタを使いやすくした物
あと、
>>116 の最後の行は紛らわしい書き方だった。
boost::functionの1つの具現化(戻り値と引数の型が同じ)においては、関数ポインタによる動的多態である。
>>117 なるほど!
多態とはまた別物なんですね。
ボリモルフィズムが一気に広がるかもと思ったんですがね。
ありがとうございました。
>>115 boost::function<void ()> で、引数は全部 bind するとか、
boost::function<void (std::vector<boost::any> const&)> で引数について型消去しながらやりくりするとか。
(´;ω;`)さ、さ、さむいお
利用者が仮想関数を呼び出す時、仮想関数の実装を知らなけば引数を渡せなくなって、ポリモーフィズムのメリットがなくなる気がするけど。
いらない
スレッドセーフのSTLクラスは使えるな。 boostのどのライブラリより上では。 boostにこんなのないだろ。
ありますがな・・・
ありませんがな・・・
TBBの日本語サンプルサイトつくってくれよ。
マルチコア時代で、CPUメーカー製の、フリーのこのライブラリは強力すぎる。
できたら毎日クリックしに行くからさ。
http://ja.wikipedia.org/wiki/Intel_Threading_Building_Blocks 抜粋
並列処理アルゴリズム
parallel_for ループ間で依存性がない単純なループの並列処理
parallel_reduce 指定した範囲をより小さな範囲に再帰的に分割し並列処理
parallel_scan 並列プリフィックスを計算
parallel_while 不明領域、動的領域変更を伴う独立したループ操作
parallel_sort 並列処理でソートを行う
pipeline パイプライン処理
コンテナクラス
concurrent_hash_map STLのmapクラスをスレッドセーフにしたもの
concurrent_queue STLのqueueクラスをスレッドセーフにしたもの
concurrent_vector STLのvectorクラスをスレッドセーフにしたもの
サンプルはないけど日本語リファレンスあるし間に合ってる感じ
もうひとつだけ例を見てみましょう。
static LONG flag;
if (flag == FALSE) {
flag = TRUE;
...
flag = FALSE;
}
このコードがまずいことはもうお分かりですね。 NT にはフラグのチェックとセットをアトミックに行える InterlockedCompareExchange がありますから、そちらを使いましょう。
if (InterlockedCompareExchange(&flag, TRUE, FALSE) == FALSE) {
...
InterlockedExchange(&flag, FALSE);
}
http://hp.vector.co.jp/authors/VA000092/win32/standard-coding.html
スレッドセーフなキューを複数個用意してキューにデータ来たら、 それぞれ直列に動作する関数を動かしたいんだけど 作業が終わったらキューを観察に行くけど無かった場合、次に入ってくるまで どうやってまてばいいんだ? ひとつとしてビジーループはあるが。 それなら別変数用意してロック掛けた方が良い。ロック無しで出来る? キューは一カ所にしてすべての処理関数スレッドで共有する方が無駄ないか。
キューに挿入する側が、余りのスレッドを監視して空いてたら処理させればいいか。 これならロック無しでアトミック命令だけでいけそう。
しかしスレッドを生成するコストも馬鹿にならないから スレッドの生成・消滅はせず、恥に生成したやつを使い回したいところ。 やっぱロックいるか。処理終了してキュー待ちのロック。
スレッドの生成は恥
wait付きのビジーループでいいか
C++でコルーチンってできないの?
boostにあるにょ
あるんだ boostまじ何でもあるな 奴らはいったい誰と戦ってるんだ
言われてみるとその言葉かなりしっくりくるよな。 C++の最適化に伴う変態記法なんて禿に親を殺されでもしない限りできないし。
>>138 部品の足りない世界じゃないの?
というかWTLもC#並に充実させてください
駆動系の部品はハイスペックだが シートもハンドルもなく部品丸出しの車
C++はC++です車ではありません 好い加減な比喩は滑稽なのでやめてください
boost.cotoutine vaultにあるにょ
145 :
デフォルトの名無しさん :2010/02/17(水) 20:52:04
>>141 部品丸出しな上
自己責任で組み替え自由な仕様だな。
146 :
デフォルトの名無しさん :2010/02/17(水) 20:52:32
>>141 部品丸出しな上
自己責任で組み替え自由な仕様だな。
>>141 部品丸出しな上
自己責任で組み替え自由な仕様だな。
車への例えがどれも的外れでワロスw
>>141 部品丸出しな上
自己責任で組み替え自由な仕様だな。
だからといってヨソの車がそんなに安全かというと……
>>144 valtですか。
ありがとうございます。
152 :
デフォルトの名無しさん :2010/02/17(水) 20:58:22
理想的には部品丸出しではないが、 バカが作ると部品を理解していなければならなくなる 仕様だな。
マルチスレッドキューでロックしないサンプルできた。読み込むに失敗・キューがないときにwaitはいれたが。 #include "include/tbb/concurrent_queue.h" #pragma comment (lib, "tbb.lib") #include <process.h> #include <windows.h> #include <iostream> using namespace std; using namespace tbb; concurrent_queue<int> que; int s[2]={0,0}; unsigned WINAPI fnc(void *n) { int x,num=(int)n; while(1) { if( !que.try_pop(x) ) { Sleep(100); continue; } if(x==-1)return 0; s[num]+=x; } } int main() { HANDLE hd[2]; int n; for(n=0; n<2; n++) hd[n]=(HANDLE)_beginthreadex(NULL, 0, fnc,NULL, n ,NULL); for(n=0; n<=1000; n++) que.push(n); que.push(-1); que.push(-1); WaitForMultipleObjects(2, hd, TRUE, INFINITE); cout<< s[0]+s[1]<<endl; getchar(); }
0から1000まで足すだけ。キューへマルチスレッドでpush、popして 読み取って空いてるスレッドが足し合わせていくサンプル。 答えは合ってたよ。
キューではロックしているだろうがな。そこを自作せずに済んだという話だ。
プログラム組んでて returnって打ったつもりだったら tryit, って打ってた なんか感動した
rをtにずらして打ってみると・・・!?
ゴルゴはtrycatchfinallyを0.5秒でタイプするらしい
161 :
デフォルトの名無しさん :2010/02/17(水) 21:33:09
HDL ではごく普通というか大前提の話なんだが 直列処理という枠に凝り固まった頭で見ると驚きの連続なんだろうな
任意の整数を返す関数が、失敗も正常フローだった場合に すっきりするエラー通知の仕方はある?
任意の整数を返す関数が、失敗も正常フローだった場合に すっきりするエラー通知の仕方はある?
任意の整数を返す関数が、失敗も正常フローだった場合に すっきりするエラー通知の仕方はある?
任意の整数を返す関数が、失敗も正常フローだった場合に すっきりするエラー通知の仕方はある?
パラメータになんか持たせるとか
なにを?
_beginthreadとCreateThreadは何が違うんですか? というかどっちを使った方がいいんですか?
C++の配列サイズ指定で変数は使えることもあるんでしょうか?それともコンパイラ依存でしょうか? MinGWで下をコンパイルは正常にでき(Warningも出ない)、arrayのsizeofは32byteとなってちゃんと確保されているようです。 #include <iostream> using namespace std; int main() { int num = 3 + 5; int array[num]; for (int i = 0; i < num; i++) { array[i] = i; } cout << sizeof array << endl; }
正確にはC++ではなくC99で使える様になったはず
>>168 CreateThreadはWindowsAPI、_beginthreadはCランタイム。
CreateThreadで生成したスレッドでCランタイム関数を使うとExitThreadしたときにわずかだがメモリリークが発生するため、
MSはそのような場合には_beginthreadを使うように推奨している。
なるほど。 参考になりました。 unix - windows 互換のスレッド関係の関数は無いんですかね・・・
Cランタイムって何?
176 :
154 :2010/02/17(水) 22:41:42
修正。引数渡す場所間違えて一スレッドしか動いていない。 #include "include/tbb/concurrent_queue.h" #pragma comment (lib, "tbb.lib") #include <process.h> #include <windows.h> #include <iostream> using namespace std; using namespace tbb; #define N 3 concurrent_queue<int> que; int s[N]; unsigned WINAPI fnc(void *n) { int x,num=(int)n; while(1) { if( !que.try_pop(x) ) { Sleep(100); continue; } if(x==-1){ cout<<"正常終了number:"<<num<<endl; return 0;} s[num]+=x;Sleep(rand()%50); }} int main() { HANDLE hd[N]; int n; for(n=0; n<N; n++) s[n]=0; for(n=0; n<N; n++) hd[n]=(HANDLE)_beginthreadex(NULL, 0, fnc, (void*)n, 0 ,NULL); for(n=0; n<=50; n++) que.push(n); for(n=0; n<N; n++) que.push(-1); WaitForMultipleObjects(N, hd, TRUE, INFINITE); int sum=0; for(n=0; n<N; n++) {cout<< "スレッド"<<n <<"の合計 "<<s[n]<<endl; sum+=s[n]; } cout<<"総和 "<<sum<<endl; getchar(); }
>>174 pスレッド windowsというのがあるが、おすすめしない。
一度にアクセスが起きるとバグった経験有り。同じ物をwindowsの命令に書き換えたら動いた。
スレッドのどれか一つ or全部の終了待ちがない気がする。
一時期windowsであっても、linuxの互換コードで書くべきだという考えが起こり 全て統一しようとしたがPthread for winがうまく動作しないので諦めた経験ある。 現在の環境で生産性の良い、短いコードで済ますのが一番という考えになった。 完成品が出来なければ意味ない。完成していれば他OSへも移植しやすい。
QtやBoostその他 ラッパライブラリじゃできないの?
Qtもboostも標準にはいってないじゃん サイズもでかいし linuxでどこでも使えるのはPthreadだけでは
182 :
180 :2010/02/17(水) 23:07:16
>>181 その方、Pthreadはいつから標準になったと申すか。
POSIX Threads, or Pthreadsのライセンスは This implementation is free software, distributed under the GNU Lesser General Public License (LGPL). え?誰も聞いてないって?
入ってないlinuxはないんでは。c/c++がコンパイル可能な環境なら。
標準っていうか、プリインストールって言いたかったわけか。
ち、違うよ。
bccなんてポンコツ捨てろよ
bccは毎年新規で販売してるんだぞ。 コンパイル速度速くて良いんだこれは。
httpサーバーなどへIf-Modified-Sinceをつける場合statでファイルの更新日付を 取得してどのように変換すればいいのでしょうか? 日本時間に直すサンプルは見かけるのですがGMTのまま文字列化する方法が わかりません
スレッドセーフキューがマルチスレッドの要なんです マクロやアセンブラ使わずに書いてくれると喜ばれますよ
STLportがスレッドセーフなSTLだった これつかお
わざわざいうな
プロの方はスマートポインタを使うのが基本とのことですが、例えば引数なんかも hoge( shared_ptr<Test>& sp )といったかんじになるんでしょうか? それとも受け渡しは生のポインタで行い、オブジェクト側でスマートポインタに格納ような 使い方ですか?
参照渡しだよ
STLportがbccでコンパイルできん
>>195 僕はクラスのメンバ関数が前提なら、
関数を所有するクラスがオブジェクトをメンバ変数に保持するときはスマートポインタを、
一時的に使うだけなら参照で渡します。
>それとも受け渡しは生のポインタで行い、オブジェクト側でスマートポインタに格納ような
一番やっちゃいけない気がするんですけど・・・
>>171 >>172 アドバイスありがとうございます。
手元のどの参考書見ても変数は使えないと書いてあってあれ?と思っていたしだいです。
Visual C++で使えないようなのでgccだけなんですね。
>196 >19 ありがとうございます。 今試してみましたが同一ポインタを複数のshared_ptrに格納すると、 shared_ptrの数だけデストラクタが呼ばれてしまうんですね。 基本は参照で複製を作らないようにするということですね。
201 :
デフォルトの名無しさん :2010/02/18(木) 22:21:29
g++やVC++などの有名どころのC++コンパイラについてお聞きしたいのですが、
コンパイル時定数を使った
ttp://codepad.org/EmT4J9d3 こんなifによる分岐があるとします。
このとき、成果物.exeはちゃんと最適化されて
分岐が消えるのでしょうか?
よろしくお願いします。
codepadで使ってるg++とVC9.0では消失を確認
ありがとうございます。 const bool ctc = 100; // compile-time constants を bool ctc = 100; // NOT compile-time constants にしても同じでしょうか? (volatileは付けません。) お手数をおかけ致しますが、よろしくお願いします。
const bool ctc = 100; // compile-time constants に関しても同じ(キャストはちゃんとした方がいい)。 そもそも実行時への互換性を保たないと最適化というのはできないからね。 bool ctc = 100; // NOT compile-time constants でも、単純にctcへの変更が無い事から最適化がなされた(204と同じ環境で)。 ただ、このケースは後のコードに完全に依存しているから考察する価値はあるのかどうか疑問だな。
207 :
205 :2010/02/18(木) 23:02:24
>>206 ご教示ありがとうございます。
そういったことは、どうやって調べればよいのでしょうか?
.asmを出力して調べているのでしょうか?
YOUバイナリ読んじゃいなYO
>>208 ありがとうございます。
asmからは逃げ回ってきているので全然読めそうにありません。
勉強しなければなりませんね。。。
別に勉強しなくても片手間にasmの命令リストと見比べてるだけだけどね。
asmってコンパイラやアセンブラによって 扱いが違うからやだ
なんかアセンブリって難しそうなイメージある 低級だから追いかけるのが大変なだけで難しい構文とかはむしろ少ないんだろうけど・・・
アセンブリ自体は簡単だけど、他の言語で出来ることをアセンブリでするとか考え出すと難しい
アセンブリで全部済むならプログラミング言語なんて必要ないわけで
そう考えるとC言語とか 移植性もあってすげえ言語だな。 今更だけど。
>>216 cが優秀じゃなくてcコンパイラ作った人が優秀なだけだな
規格作ったやつだ。 Cコンパイラは、上司が監視して下っ端が要求通り作ってるだけ。 初めの設計図が一番。 たとえば、アニメは動画マンという超低賃金のやつらがやっているが 宮崎駿や原作漫画家がいるから開発できるんだ。
>>218 現存するコンパイラは確かに規格ありきで作り始めてそうだけど、元々は
たくさんの環境向けに作られていた C の共通部分を元に規格化されたんだから、
先にコンパイラ作ってた人が下っ端ということはないだろう。
>>219 まあ初期のC言語確立やコンパイラ作ったような人たちは
上も下もねーだろうな
小さいチームで多少リーダー的存在がいるくらいだろうし
そういう中で試行錯誤しながらとかだろうし
その後の各環境ごとのコンパイラ開発はC言語そのものがあるんだし
それにあわせちゃえばいいので作業だろうな
(でもそれなりに知識は要るので下っ端ってわけじゃないだろうけど
>195 そんな渡し方したら危険じゃない?
ファイルIO( open close load)がかなり時間かかるから 要求を並列で出しておくと時間短縮するね。 細かい多数のファイルで2倍-3倍くらいの向上。
5倍を目指してくれ
files=20
dmr にあやまれ。
How many files(0-15)?■
じじい乙
ここの人ってワイルドカード欲しい時に何使ってるの? boost使ってる人なら正規表現なんだろうけど、 使って無い人が気になる。
windows api か 正規表現で代用
俺は魔法だなあ
231 :
デフォルトの名無しさん :2010/02/19(金) 21:12:55
そもそもワイルドカードと正規表現がどうつながるんだ?
ワイルドカードでできる事は正規表現でできるだろ
233 :
デフォルトの名無しさん :2010/02/19(金) 21:31:27
C++ でできる事はアセンブラでもできるんだが そういう問題ではあるまい?
何を言ってるんだ…
異常なし
暇な人とは失礼な 改めていわれなくてもこんなところ見てる段階で暇・・・
238 :
デフォルトの名無しさん :2010/02/19(金) 22:05:30
>>233 正規表現が無い環境だってあるじゃない。
外部ライブラリも不可とか。
その例で言うとC++が使えない環境という事。
「C++使えないなんてあるわけないじゃん」とは言えまい?
>>238 C++使えないって、組み込み系とかですか?
なんかろくなコンパイラがないってことなんでしょうか。
>>239 例えばの話です。
組み込み系なんてサッパリ^O^
なんで2つの言葉のつながりから、環境がどうこうの話になるんだ。 話の流れ方に病的なものを感じる。
病的っていうか、知ったばかりの単語を中学生が使いたがってるだけな雰囲気
243 :
デフォルトの名無しさん :2010/02/19(金) 22:26:19
>>238 あったねー、OS にワイルドカードがなくてアプリが独自にサポートしてたケース
アプリごとに微妙に解釈が違ってて脱力ずっこけが何度もあった
>>239 C++ 自体はどのシステムにでも使えるぞ、C++ で HEX や HDL が作れるわけで
>>235 パッと見だがリークすると思う
t = new Test;
を解放してない
delete t;
が必要じゃない?
聞く前にop new/deleteでカウントするぐらいはやってみようよ
246 :
235 :2010/02/19(金) 23:07:57
>>244 見落としてました。
>>245 new、deleteをオーバーライドってことでしょうか?
やってみます。
どうもありがとです。
Test *New(int index0,int index1,int index2); の途中で失敗した場合のリークも
worker threadパターンを実装したいので 既存の関数を実効させる部分をテンプレートで 実装したいのですが、どのように書けばいいのか わかりません。 たとえば、f1、f2、f3を同じworke threadクラスで 扱うにはどのようにコーディングするのが正しいのでしょうか
スレッドを起動させっぱなしにするのがワーカースレッドっていうのか。
>>176 のunsigned WINAPI fnc(void *n);もワーカースレッドだな。参考にしてくれよ。
>>176 は一つのキューに挿入と取り出しを行い、3スレッド並列で空いたら
スレッドからデータを取り出し処理を行う。
キューが貯まったら各関数に通知したら、ビジーループを防げるけど 面倒なので100ms毎に確認しに行くようになっている。
プログラムする時のやり方聞きたいんだが いきなり書き始める? きっちり考えて書く? 書き始めたとしても、ヘッダでインラインで書きまくって、動作したらcppと分割する? それとも最初からわけて書く?
自分の場合大まかな方針は決めてから書く ただ、確実にこれはいるなってデータや関数は あまり考えないでも書く ヘッダにインラインで書くのはコンパイル時間との兼ね合い 大きいプログラムを書くときは最初から分ける 俺のオススメは 2回同じことを書くまでは出来るだけ抽象化しない 逆に2回同じことを書いた時点で必ず抽象化する こうすると、バグの発生源が重複しないので大分バグをつぶしやすくなる ただ、多人数での開発には使いにくいだろうが
>>252 まず絶対UMLとシーケンス図を書く
その後細かいところはフローチャートを書く
2、3時間でできることだから必ず行う
その後1回で製造する。
>>252 いきなり書く。
パフォーマンスを計る。
もう一度書く。
ライブラリ化する。
いきなり書くやつは下っ端だな。与えられる仕様をただこなすだけ。 ビル・橋・道路の設計者ではなく、日雇いの土木作業員。
まぁ、いきなり「本番」のコードを書くのは無謀だと思うけれども、 頭の中で色々練っている最中に、その助けとしてちょこちょこ手を動かすことはある。 メモというかスケッチというか、そんな感じのコード。 で、その一部が断片的に「本番」に流用されることならある。
すらすらとコードが書けないときは何かが間違ってるというのはあるねぇ
図に書く スクリプトで書く 遅いところをC/C++に置き換える 寝る
まずコメントを先に書く トイレに行く コードを書きながら飯を食べる コメントを直す
冷静に考えればいいだけだろうがばかどもが
やりたい事を考える 下っ端に薄給で作らせる
継続での脱出みたいなことってC++で出来ますか? たとえばこんな関数があったときに、どこかでret=trueになったら 一番最初にfを呼び出した箇所へ飛んで関数を終わらせたい bool f(){ bool ret=false; //処理によってret=trueになったりならなかったり for(int i=0;i<n;++i){ret|=f();} return ret; } gotoで抜けられるのは今いる関数内のループだけだと思うので無理?
>>263 たとえば、例外的なことがおきたときにプログラムの実行を中断したいというのであれば、
例外が使える。
だけど、例外は例外的な事以外に乱用すると非常に見通しの悪いプログラムになるから注意。
>>263 bool f(){
//処理によってret=trueになったりならなかったり
for(int i=0;i<n;++i){if(f())return true;}
return false;
}
makeって使ったことがないのですが、 勉強した方がいいのでしょうか。
いい
IDEに任せっきりでmakeってのから逃げまくっていたのですが、 やっぱり勉強します。 ありがとうございます。
tbbを実用で使い出したけど、メモリ関係の例外が出まくるぞ。 いつもではなくたまに。どうみてもエラーになり得ないところで例外。 そのためにtbb_allocがついているのか。 メモリ管理をtbb専用で全部置き換えれば直るんですか。
>270 >いつもではなくたまに。どうみてもエラーになり得ないところで例外。 使い方が間違ってて排他処理で失敗してるだけじゃないの?
そうか。試しに全書き換えでやってみる。
#define allocator scalable_allocator とやると、 std::allocator がstd::scalable_allocatorになる。 std::allocator がtbb::scalable_allocatorにはどすればいい。 ::がdefineにかけない。
#define std tbbにしたらエラーでまくり。当然全関数対応しているわけはなく。
namespace std { typedef xxx::myallocator myallocator; } #define allocator myallocator
できないです template<typename T> class scalable_allocator; となっていて、テンプレート引数が必要と出ます
単純なdefineの文字置き換えで出来ないかと考え中。 stdをstd0に書き換えて、tbbをstdにして、ここでヘッダを読み込み std0をstdに戻せば、善さげなきはする。 別名で存在している関数をdefineで置き換えたらいけそう
駄目だった 再定義とか出る
バグの温床になりそうだな
悪夢だ・・・
アロケータの置き換えはTBBのチュートリアルにやり方が書いてある
面倒になってきたので標準装備のみで0から作るぜ
std::vector<int, tbb::scalable_allocator<int> >などとその都度指定する、 それをtypedefするというのは駄目なの?正統派だと思うのだけど。 C++0xなら template<typename T> using vector_tbb<T> = std::vector<tbb::scalable_allocator<T>>; と書いて、vector_tbb<int>とかvector_tbb<std::string>とか書けるようになるんだけど、 まだ未来の話……。
if文で真偽値を評価すると真になる要素がいくつあるか数えるのを短く書きたいです。 vector<int> a; // ;;;;;;; int n = 0; for(int i = 0; i < a.size(); ++i) if( a[i] ) n++; これを、 int n = std::count( a.begin(), a.end(), ?? ); ぐらいに短く書きたいのですが、なにかいい方法あります
ファンクタ使えば?
int n = a.size() - std::count(a.begin(),a.end(),0);
みなさまありがとうございます。
>>285 クラスを定義しようとすると、結局長くなってしまいますし、離れた場所に書くことになるため気に入りません。
>>286 それが良いですね。勉強になりました。
intの場合はそれでいいのですが、もうすこし一般化して、 if( a[i] >= 0 ) の場合などにも使える方法はありますか?
>>287 関数内クラス
boost::lambda
c+0x lambda関数
>>287 count_if(a.begin(), a.end(), bind2nd(not_equal_to<int>(), 0))
みたいなのをちょっとずつ変えれば
トークン結合演算子##を利用して どうにかならんかね?
関数内にしかスコープのない関数って作れる? void foo(){ std::cout << "foo\n"; } の中で void foo(){ void bar(){std::cout << "bar\n";} bar();bar();bar();bar(); std::cout << "foo\n"; } こんな風に。 普通に考えてC++では違反だと思うのだが、 どうにか回避するトリックとか。
ローカルクラスは結構便利なんだけどなぜかあまり浸透してないよね
だってtemplateで外部にクラス渡せないし
名前空間やモジュールシステムを持たないJavaScriptのような言語ならともかく C++ではあまり必要性がないと思う。ローカルクラスや関数内関数 クロージャはまた別だけど
ローカルクラスはtemplate引数も使えない。 あと0xでlambdaの型が外部に渡せるのに未だ渡せないローカルクラスは生きている意味があるのかと問いたい。
fainalなクラスとか? ローカルクラスにできて他にできないことって特にないよなぁ ローカルのほうが散らかさないで書ける場合はあるけど
「外部に渡せる」の意味がわからん
ローカルクラスは昔使ってたけど、関数が大きくなって読みにくくなるんで匿名名前空間に置くようになった。
ローカルクラスはデストラクタで自動でリソース解放するのにたまに使ったり。 (=スマートポインタのデリーターみたいな感じ。) それとC++0xからはテンプレート引数に渡せるようになるね。
× デリーター ○ カスタムデリーター です。
無名の名前空間だとヘッダに書かないといけないテンプレートクラスに使えないね
303 :
291 :2010/02/22(月) 00:16:05
std::string str[] = { "A", "B" }; これってバグの元になる? int i = sizeof(str) / sizeof(str[0]); こうするときとかに。
動的配列であってもその実体は内部にelementのpointerを持っているだけなので 中身のデータが違ってもインスタンスの大きさはそれぞれ同じ。
>>305 即レスかつわかりやすい説明ありがとうございます。
不安がなくなりました。
C99で絶望するがよい。
素直にvector<string>使いなよ。
std::string a = "asdf", b = "9999999999999999999999999999999"; って文字列の長さが違うからsizeof(a)とsizeof(b)で同じ数値になるの!? std::stringで配列作っていいの!?!?!??!?!!!???わかんないです><;;;;; → のーぷろぶれむ
311 :
304 :2010/02/22(月) 01:15:14
>>310 ありがとう。
その通りでした。
>>308 あとあと編集しづらいかな見にくいかなと思ったので。
クラス内にstatic constのint値を定義して, #defineの代わりにしたいんですが, このint値はそのクラスのインスタンスを生成してなくても, メモリ上に存在するのでしょうか? そうなると,大規模開発では避けるべきなのでしょうか?
#defineされた値だとプログラム全体の最適化がされない限り書く度に別々のところに数値が配置されるけどね。
グローバル変数ってlibファイルで共有? モジュールで共有?
>>312 まあ理屈はそうだけども、
現実的にはその最適化がなされないような状況は
明示的にコンパイルオプションで止めろ!
と言わない限りおこんなinじゃない?
staticなんだからインスタンスは関係ないんじゃ
templateクラスのstatic変数ならあるいは
来月出版の C++テンプレートメタプログラミング 糞本かな? えぴなんとかさんの書いた類の糞本レベル?
321 :
デフォルトの名無しさん :2010/02/23(火) 05:41:33
禿本の邦訳にも係わってる人だよ
えぴなんとかさんってすごいのかどうかよくわからん 昔の掲示板ログとか見るととんちんかんな感じだよね えぴなんとかさんが初心者だったころなのかもしれないけど
わんくま同盟ってなんか気持ち悪いよね 公開しているドキュメントでお世話になってはいるけど、近づきたくない感じ
気持ち悪いというあいまいで感覚的な概念が気持ち悪い
単に偉そうでむかつくんだろ
「気持ち悪い」のはともかく、「よね」が意味わからん
内輪ネタを表に出したがるあたりと偉そうなのはむかつくが同意は求めない
えぴなんとかさんって インなんとかさんみたいなもんか?
ペンネームに機種依存文字を使うプログラマの人って…
ビル☆ゲイツの悪口はそこまでだ
C++学ぶのにいい本ありませんか?
>>330 今チェックしたんだけど
機種依存文字じゃなかったぞ
>>332 こいつはマルチポストだから相手にしないように!
単項演算子-のオーバーロードについて質問があります。 独習C++という本で勉強しているのですが、以下のようなサンプルコードがあります。(※一部省略) class coord{ int x,y; public: coord(){x=0;y=0;} coord operator-(coord ob2);//2項負符号 coord operator-();//単項負符号 }; //単項-をcoordクラスに対してオーバーロードする coord coord::operator-(){ x=-x; y=-y; return *this; } 上記の場合、 coord ob1; coord ob2; ob2=-ob1; としただけで、ob1の内容が変わってしまうと思うのですが、 このサンプルコードは正しいのでしょうか? 以下のほうがいいと思うのですが。 //単項-をcoordクラスに対してオーバーロードする coord coord::operator-() { coord temp; temp.x=-x; temp.y=-y; return temp; }
俺もそのほうが良いと思う 一般に組み込み型と同じ挙動になるようにデザインするほうが良いと EffectiveC++にも書いてあるし
そしてconstを付けるべき
>>336 君の意見は正しい。
coord coord::operator-()const;
とすれば納得できると思う。
340 :
336 :2010/02/24(水) 19:57:51
>337-339 ありがとうございました。 これで先に進めます。
ん *thisを返すからいいんじゃないの?
this->xが変わるからダメなんじゃないの
プログラムに致命的なエラーがあり (取り扱えない例外をキャッチしたなど。) そこで即座に終了したい場合、 assert(0); exit(1); のどちらが望ましいのでしょうか? また、この2つにはどんな違いがあるのでしょうか? よろしくお願い申し上げます。
>>342 ああ、すまない。ぼけてたorz
もう寝る…
>>343 assertは、ここでこうなってるはずがない、というプログラマの意思表示
んで、それはリリースビルドだとなくなるロジック
346 :
デフォルトの名無しさん :2010/02/24(水) 23:59:19
インターフェースと実装を分離したいと思ってて、pImplイディオムを利用しようと考えています。 一般的なpImplイディオムは、コンストラクタでimpクラスをnewしていますが、 いま設計しているpImplを利用したクラスは、何度もインスタンス化されるので、newしたくありません。 また、Factory関数を作って、利用者側にわざわざ呼ばせたくありません。 つまり、クラスの利用者から、実装クラスを隠蔽し、かつインスタンス化時に何度もnewしないような方法はありますでしょうか? (妥協して、メンバ変数だけインターフェース部に持ってきて、実装クラスをSingletonにする、など考えてみましたが、案の定イマイチでした)
一つ一つ中身が違うならプールして再利用ぐらいしか思い付かないなぁ
>>343 その用途だと abort() あるいは terminate() が正解だと思う。
assert() と exit() 含めて、それぞれの違いはライブラリのドキュメント読んでね。
>>346 new したくないっていうのは動的メモリ確保のコストを嫌っての話だよね?
そういうことなら、外側のクラスに char impl_storage[max_size] みたいな領域だけ
置いといて、実装クラスでは new (impl_storage) impl(....) すればいいかもしれない。
>>346 dlmallocなんて単純だからすぐ作れるし
自分でmalloc作ればいいよ
>>346 まず、ふつうに new する状態でパフォーマンスに問題があって、次にそのボトルネックが
new にあるという確認を済ませ、さらに >350 の言うように dlmalloc などによる高速化を試みた後、
それでも問題が残るようなら >349 のような奇怪なコードを、十分なコメントを添えたうえであれば、
書いても良い。
それ以外は許さん。
>346 実装インスタンスのnewコストを気にするんだったら、不要になったら再利用できるように簡単なGC作ったら? 実装インスタンス自体は利用者から見えないから、別にFactory関数で管理しても問題ないだろうし。 お手軽に実装するんだったらboost::shared_ptr + deleterかね。
>>343 assertは開発作業中のマーキングや「しおり」のようなものだと考えたほうがいいと思う。
exitはatexitの登録関数やストリームI/Oの後始末をしてから終了する。
C用の例外の代替物と見るべきで、C++では使わないだろう。デストラクタは実行されないし。
terminate(abort)なら後始末もせずに割り込みを掛けて即座に終了するが、
そこまでしたい状況は考えにくい。
結局、例外をそのまま放っておいてmainでキャッチしてreturn 1;とかするのが
常道だと思う。
>>343 取り扱えない例外ははじめからキャッチするなよ。
万一そんな状況がやむを得ないとすれば、 throw; で外に向けて投げとけばいいよ。
そうすれば勝手に terminate() するかもしれないし、誰かがキャッチしてくれるかもしれない。
enum型を引数に持つときって参照渡しにした方がいいの? 構造体とは違うっぽいのでしなくてもいい?速度的に
>>355 速度が気になるなら計測してみるがいい。
参照渡しがよくあるポインタと同様の実装だと考えると、 enum のサイズがポインタより
大きくなることはなさそうで、あまりメリットはなさそうな感じではある。
>>355 列挙型の実態が整数"ではない”実装を見たことがない。
>>357 別に配置newは嫌いじゃないですが、必要ないところで使うような人は嫌いです。
誰もつっこまないけどchar impl_storage[max_size]なんてしたらアライメントどうするんだよ。
>>360 boost::aligned_storage あたりでおきかえる。
じゃあ最初からboost::aligned_storageって書けよ
363 :
349 :2010/02/25(木) 12:07:15
>>362 boost::aligned_storage は標準ライブラリでもないし、コンパイラの拡張機能で指定した
ほうがいいかもしれないし、その場で適当な union 作ってしのぐのがいいかもしれないし、
そんな気持ちを込めて「〜みたいな領域」と書きました。
364 :
343 :2010/02/25(木) 12:49:32
>>363 >そんな気持ちを込めて「〜みたいな領域」と書きました。
どう考えてもそれだけの情報からその気持ちは伝わらないから。
頭大丈夫?日本語分かる?精神鑑定してもらったら?
解析で使う A-Z a-z 0-9 1 1 2 3 2 1 2 3 3 4 な表ってなんて名前だっけ?
>>366 LR解析表なのか?状態複数あって
LR衝突してないのか?
>>367 表の中は説明で適当に書いただで意味はないんだ。
どんな名前だったか忘れてしまったもんで。
助かったよ。ありがとう
>>365 俺には伝わっていたが、伝わらない人がいるのもわかる。
そして、伝わらなかったからといってそのようなレスをするあなたが心配です。
一般に、 g++ -lhoge test.cpp という調子でライブラリを読み込んで成功したとき、 hogeの場所を知るコマンドってありますか? 具体的には g++ -llapack test.cpp なのですが、これは Fortranのライブラリをリンクしているそうです。 Fortranでは DSYEV という関数名なのがC系だと dsyev_ と、アンダーバーがつくようになるというのがよく分からないので・・・。
よくわからんが、場所っていうのはディレクトリ名じゃなくて関数名のことかい それにOS依存の話題だったら微妙にスレ違いだぜ
LD_LIBRARY_PATHとか
・リンカが検索に用いるパスを探すことで場所を知ることができる ・ラッピングした際に小文字にしたんでしょう
>>370 http://www.netlib.org/clapack/faq.html As previously stated, the CLAPACK library was built using
a Fortran to C conversion utility called f2c. The entire
Fortran 77 LAPACK library is run through f2c to obtain C
code, and then modified to improve readability. CLAPACK's
goal is to provide LAPACK for someone who does not have
access to a Fortran compiler.
It is important to note that this f2c conversion was run on
a machine that appends an underscore to differentiate C
and Fortran 77 namespaces. If your machine does not append
an underscore to differentiate namespaces, then CLAPACK
will not work on your machine.
ありがとうございます。 だんだん事情が分かってきました。 人間がCに移植しているわけではないのですね。 clapack.h をみても、単に宣言が書いてあるだけなので、 Cのソースコードとしてincludeするわけでもないのか。 あと前半はたしかにOS依存の話ですね。 手元の環境ではLD_LIBRARY_PATHも空だったし。 すみませんでした。
376 :
デフォルトの名無しさん :2010/02/26(金) 20:04:26
/*******************************************************/ #define MAX(x,y) ((x)>(y) ? (x):(y)) int a = 3; int b = 3; int m = MAX(a,++b); はプリプロセッサによって int a = 3; int b = 3; int m = ((a)>(++b) ? (a):(++b)); と展開されます。 結果的に++bが2度評価され、bとmは5になってしまいます。 /*******************************************************/ という記述を見たのですが、標準C++の規格ではbとmは5になるってのは保証されますか? 私には未定義の動作になりそうに見えるのですが。 よろしくお願いします。
保証されますよ
>>377 int m =++b, a , ++b;
の場合はどうなりますか?
bとmが5になりますか?
それとも未定義の動作でしょうか?
未定義の動作ですよ
int m = (a)>(++b) ? (a):(++b); だとOKで、 int m =++b, a , ++b; だと未定義の動作なのですね。 うーん、ややこしいです。 両方とも一つの式の中で2回bの値が 変化しているように思うのですが、 どういった相違により 片方がOKでもう一方はダメに なるのでしょうか?
カンマがね、ヤバイんですよ・・・ここだけの話
unsigned A(){ struct{unsigned a;unsigned operator()(int x){return ++a<<x;}}r={1}; retrun r(0)|r(8)|r(16)|r(24);} 0x04030201 // 式中でオブジェクトの順状態て保証される?
なんか関数の実引数の区切りのカンマと、カンマ演算子を間違っているやつがいるようだ。
>>378 の m, b ともに 5 になることは保証されているぞ (5.18-1)
m=func(++b, a, ++b); だと未定義動作だけどな。
>>376 副作用完了点でぐぐってみるべし
a++, a++; 未定義
386 :
380 :2010/02/26(金) 22:23:55
int m=func(++x, ++x); が未定義動作というのは全会一致ってことですね。 int m = (a)>(++b) ? (a):(++b); は正当で int m =++b, a , ++b; も正当 ですが int m =++b, ++b; は未定義ということなのですか? int m=(++x) + (++x); は未定義動作になりますか?
未定義
>>384 int a=3;
int b=3;
int m =++b, a , ++b;
このときにmが5になることが保証されているといっている?
>>384 カンマ演算子は副作用完了点たりえないのでは?
391 :
390 :2010/02/26(金) 22:45:15
間違えて覚えてたみたい。ごめんなさい。
392 :
384 :2010/02/26(金) 22:46:49
章番号までちゃんと示してある。言語規格書呼んでから話するんだな。
>>392 自信満々のところ水を差すようだけど、 >389 の言うとおりコンパイルエラーになると思うんだ。
カンマ演算子とか言ってるところを見ると、
int m =(++b, a , ++b);
こう解釈したんだろうとは思うけど。
特例は3項演算子、カンマ演算子のほかに&&と||もあるから int b=1; int a=++b&&++b&&b; こんなのでもちゃんとa=3になるな しかしひどいコードだ
もういいから黙って二行に分けろよカス
何そのイン○リさんみたいな返し?流行ってんの?
何言ってんだか
>>393 コンパイルエラーにはならず、カンマ演算子の最後、つまり2回目の++bが値として使われるので
mに4が代入された後、bはインクリメントされる。
なので、
>>388 を書いた。
>>399 なんだか知らんが
++bは前置増分演算子って呼ぶってことは知ってるの?
つまり 3項演算子(条件演算子 カンマ演算子 && || の4つは、副作用完了点となるから それらのオペランドに++aが複数回出現しても 未定義の動作にならないってこと?
>>400 なんだかどうしようもないところでボケていてすまんかった
>>402 「オーバーロードされてなければ」それで合ってる
ttp://codepad.org/AsWip2mX このコードで
std::cout << hairetsunoyousosuu(arr) << std::endl;
の部分は 期待通りになるのですが
std::cout << foo(arr) << std::endl;
の部分が期待通りになりません。
どうすれば
「引数として渡された配列の要素数を返す『関数』」
が書けるでしょうか?
よろしくお願い申し上げます。
関数の仮引数の[]はただのポインタに変わる コンパイル時にわかるものなら_countofを参考にする それをDLLとして公開するとか誰が渡すんだかわからないものを自動で取得する汎用的な方法はない
>>405 main::arrはint[5]型
foo::argはint[]型
sizeof(int[5])はsizeof(int*) * 5
sizeof(int[])はsizeof(int*)
int*とintの大きさがたまたま同じだっただけ。
>>406 ポインタとは違ってmainで定義したarrの要素全部がコピーされるけどね。
構造体と勘違いしてんじゃねえのお前
こまけぇことはいいんだ、vector使え!
412 :
405 :2010/02/27(土) 19:19:17
>>406-411 みなさんありがとうございます。
template<class T, int N> int len(T (&)[N]){return N;}
と
#include <cstddef>
template<typename T, std::size_t N>
char (&lengthof_helper_char_array(T (&a)[N]))[N];
#define lengthof(a) (sizeof(lengthof_helper_char_array(a)))
ですと、どちらが望ましいのでしょうか?
>>412 どちらが望ましいかは場合によるね。
前者はコンパイル時定数としては使えない。
後者はコンパイル時定数として使えるようにしてあるけど、そのために読みにくく
なっているし、基本的に避けるべきであるマクロまで組み合わされている。
>>413 なるほど、そう言った違いがあるのですね。
ありがとうございました。
ttp://www.kijineko.co.jp/tech/superstitions/parameter-of-isalpha-is-char.html ここに書いてあることについてお伺いしたいのですが。
const char str[] = "abc123";
for (char* s = str; *s != '\0'; s++)
{
if (isalpha(static_cast<unsigned char>(s)))
{
...
}
}
こうすべきとのことですが、これは
const char str[] = "abc123";
for (char* s = str; *s != '\0'; s++)
{
if (isalpha(s))
{
...
}
}
の用にキャストを外すと動かないことがあるということでしょうか?
"abc123"のように、内容全てがASCII文字であってもだめなのでしょうか?
よろしくお願い申し上げます。
>通常は問題ないのですが、多バイト文字を含む文字列の各要素を順に is 系関数で調べる場合などは、
>>416 多バイト文字を含む文字列の各要素も
isalphaでアルファベットかどうかを調べることが可能と言うことでしょうか?
たとえば
"あいうえおabcd"
のような全角文字でもできるのでしょうか?
その記事も含めてそんなことをいってる奴は居ない
> is 系関数に実引数として渡すことができる値は、0 〜 UCHAR_MAX または EOF だけです
ASCIIだけなら問題ないんじゃない? 他の文字コード入ってたら知らんけど
"abc123"は多バイト文字を含む文字列ではありませんよね。 では多バイト文字を含む文字列の各要素を順に is 系関数で調べる場合など とは、具体的にはどんな文字列のことなのでしょうか?
sjisとかunicodeとか。 isalphaのかわりに_ismbcalphaやiswalphaで調べられる。
3の倍数のときだけ多バイトな文字列の例. "123456789"
それスゲー迷惑だけどオッサンが漢字キーを駆使しながら頑張って作ったものだと想像するに少し許せる 正規表現置換とかだったら死刑
文字コードって訳わかんない ひとつに絞って他のコードは国際法で規制しろよ
>>425 トロンコード最強ってことで。くっくっく。
>>415 isalpha()に「0〜UCHAR_MAX または EOF 以外の値」が渡された時の動作は未定義
ということはわかっているのかね。きじねこは不可解な動作やらクラッシュという表現をしてるが
例えばstrにSJIS全角文字「A」(コード0x8260)を含んでいたとして(str="Aabc123"とか)
forループ内でisaplha()に、0x82、0x60と渡されていくことになるが、
例えばcharが符号付きでint型が32ビットの処理系だと0x82→0xffffff82と
符号拡張で変換されるから「0〜UCHAR_MAX または EOF 以外の値」となって未定義となる
unsigned charにキャストしとけば「0〜UCHAR_MAX または EOF」には納まる
このきじねこの記事雑だな
constや*忘れてる
428 :
415 :2010/02/28(日) 00:34:56
hoge *p = new hoge; my::smp q(new hoge); // ok my::smp r(p); // no! 上の初期化法だけを許可したいんだけど、方法はある? つまりテンポラリなポインタだけを受け取れるような方法 C++0xだと右辺値参照というのがあるからできるらしいのだけど・・・ 今ではまだメタプログラミングを駆使しても不可能かな?
無理。my::smpのコンストラクタ内でnew hogeを実行するようにすれば近いことはできるんじゃない? 引数付きのコンストラクタも考えると現実的でないが
>>430 thx
コピーコストが気になるけどその方向で考えてみますわ
boostにそんなのがあった気が
433 :
デフォルトの名無しさん :2010/02/28(日) 23:34:24
テンプレートクラスについてお聞きします。 テンプレートクラスは、ヘッダファイル内に関数の実装の定義も書きますよね? もしテンプレートの特殊化をした場合は、cppファイルに書いていいものなのでしょうか? たとえば、テンプレートパラメータにbool値をとるクラスを定義したとして、 関数の実装をヘッダファイルに書かず、 テンプレートパラメータがtrueのときの処理と、falseのときの処理を それぞれcppファイル側に書いてもいいものでしょうか? (そのようなクラス設計がいいかどうかは別として・・・)
>>433 まずいだろう
他のファイルからもそのヘッダファイルを参照していたらどうなる?
>>433 いいよ
template<bool A>
struct X
{
void f() {}
};
template<>
struct X<true>
{
void f();
};
とヘッダーに書いて
void X<true>::f(){}
を別のコンパイル単位に書くのはOK。
bool が typename でも同じ
436 :
デフォルトの名無しさん :2010/02/28(日) 23:51:44
クラス設計に関して質問です。 Waveファイルの入出力に関するクラスと、再生に関するクラスの2つを作ったとします。 実際waveファイルを入力して、再生するというプログラムを書く場合オブジェクトを何にしたらいいでしょうか? オブジェクト指向がよくわかっていなくて・・・
// ヘッダファイル template<bool B> struct hoge { hoge(); }; // ソースファイル template<> hoge<true>::hoge() {} template<> hoge<false>::hoge() {} これで問題ないね
438 :
433 :2010/03/01(月) 00:18:10
>>436 WaveIO obj = new WaveIO(filePath);
Player obj2 = new Player();
obj2.Play(obj);
とかってなるんでないの
マルチスレッドキューありますか。 自作しようして無理だった。
>>432 make_sharedだな。TR1にもC++0xにもある。
>>440 Intel TBBになんかあったはず。
クラスのメンバ関数とそのconst関数の共通化をしようとして失敗しています。
以下のコードでは [ ]演算子のオーバーロードがその例です。
どうしたら理想([ ]によるメンバ変数arrayの中身変更)的な動作になるでしょうか?
http://codepad.org/9YXChfJT
高校1年の春、2年生に進級する直前のできごとでした。 僕は難関、最初の壁と名高いポインタにぶつかりました。 ポインタ・・・彼は僕を苦しめました 存在が意味不明でした。 『本当に必要なのか? いつ、使うの?君はなんなんだい?』 僕は寝ることをやめて飲まず食わず 1週間、ずっとポインタを見つめた結果 理解できませんでした・・ そのときの挫折はまさに、絶望でした。 自分の理解力の無さと頭の悪さに怒りを覚え その怒りはそのうちに悲しみにかわり 僕は1ヶ月、眠れませんでした。
>>442 × return const_cast<double&>( static_cast<const Test>(*this)[pos] );
○ return const_cast<double&>( static_cast<const Test&>(*this)[pos] );
そんな僕がまたプログラマ目指そうと思ったのですが どう思います?
>>445 好きにすればいい。分からない事があったらここに書き込めば俺は答える。
>>444 ありがとうございます。
<間違い> return const_cast<double&>( static_cast<const Test>(*this)[pos] );
は、static_cast<const Test>(*this) で *this の中身をコピーした const Test型 のオブジェクトを生成し、
その生成されたオブジェクトに [pos] でアクセスしている。
だから、実際には *this の中身にアクセスできていない。
という解釈で良いでしょうか?
>>442 こういうのも
return const_cast<double&>( static_cast<const Test*>(this)->operator[](pos) );
450 :
442 :2010/03/03(水) 04:18:56
451 :
デフォルトの名無しさん :2010/03/03(水) 07:50:18
ツリーのクラス構造について質問です。 現在、以下のようなクラスを考えています。 class Base{} class ParentBase : public Base { }; class Parent : public ParentBase { }; class ChildBase : public Base { }; class Child : public ChildBase { }; class ChildA : public Child {} class ChildB : public Child {} class ParentA : public Parent { public: ChildA childa; ChildB childb; }; class ParentB : public Parent { public: ParentA parenta; }; Parentの派生クラスは、メンバ変数でChildだったり、Parentのオブジェクトの実体を保持します。(例:ParentA, B) ここで、各Parentが保持するオブジェクトから、親オブジェクトへアクセスする方法はないでしょうか? やりたいことは、ParentA::childaで、ParentAの関数を呼ぶ、ParentB::parentaで、ParentBの関数を呼ぶ、ということがしたいのです。 一番基底クラスのBaseクラスで、Baseクラスへのポインタ持たせてやろうと思ったのですが、そのポインタへの実体のセット方法がわからなくて、迷ってしまいました。 何かいい方法はないでしょうか?
ポインタを理解したのは、確かポインタ渡し、参照渡し、値渡しの違いを知ったときだった憶えがある
>>451 コンストラクタで渡すなりセットするメンバ関数を作るなり public にして設定するなり、
いろいろあるだろ。何が気に入らないんだ?
struct hoge: public unary_function<int,int> { int operator(int); }; 的な関数オブジェクトを g++ -Weffc++ hoge.cpp でコンパイルした場合、 warning: base class struct std::unary_function<int, int> has a non-virtual destructor というエラーがどうしても出るのですが、 ライブラリの責任であってユーザ側からは対応しようがない、 というので正しいでしょうか?
protected継承
>>456 要するにGCCがそうだと言ってるからそうだ、ということですね。
これに対するライブラリ実装者の答えが欲しいのですが・・・。
>>457 >456 のリンクをたどると、 >454 の警告に関する gcc の「バグ」報告に連れて行かれて、
その報告は今でも "NEW" として残っているんだが、何か違うものが見えるのかい?
そう読むのか。 コメントのほうを読んで誤解してしまいました・・・。 ありがとうございます。
>>454 が何を問題だと言っているのか判らない。
もしかして、Effective C++ 読まずに問題視してる?
調子に乗って struct を class みたいに使うのが悪いんじゃね?
どうせポリモルに扱わないんだからほっとけよ
464 :
デフォルトの名無しさん :2010/03/03(水) 22:37:41
>>454 どこに「エラー」って書いてあるんだよ
もしかしてエラーと警告を混同してるか?
C++のキャストって長ったらしくてあまり使わないんですが, 実際C++のキャストで助かった&Cのキャストではまった 経験をお持ちの方っていますか?
C++スタイルはデバッグで見つけやすい
>>465 キャストは奨励できないからC++のキャストは長い。
キャストにも色々な目的があるので種類がある。目的に合わない変換不可能なものにはエラーが出る。
あらゆる変換ができるCスタイルのキャストはバグを見つけにくいので使わないほうがいい。
long longな値をstd::fstreamに<<すると三桁区切りにcommaが入ってPCが爆発するんだけど 書式設定だとか弄ってcomma入れないような設定できなかったっけ?
>>465 意図しない、または、意図した以上のキャストをコンパイル時に発見できる
>>468 localeとfacet
thousands_sep()が返す値を確認するとよい
C++スタイルのキャストでコンパイルエラーがでる度に助かっているわけだ
>465 検索が簡単。
分かってても、警告がうざい&タイプが面倒だから、使ってしまう(int)キャスト
dynamic_castの機能はCスタイルのキャストでは実現できない
キャストの多さは設計の不十分さを示す良い指標
dynamic_castはゆとり const_castはバグ
stdの特殊化が許されてるのはswapだけですか?
ていうかstatic_castも暗黙的な変換ができないポインタ変換に対して使えちゃうだろ。 static_castは甘え
dynamic_castを使う設計てどっかミスってるはず ダウンキャストするんだったら自前の仮想関数テーブル作れよって話しだ
いやdynamic_castでいいだろw
>>481 アップキャストした後にダウンキャストとかポリモーですらないじゃん
クロスキャストなんてboostにそれ専用のがあるだろ?
>>483 うるせーテーブル作らせろ
いやまじでダウンキャストとか使う場面なくね?
面倒だからやっちゃえとかならわかるんだが
同意 内部でdynamic_cast使ってるboostとか糞だよな
RTTI嫌ってるやつって厨二病みたいなもんだろ?
RTTIは遅くなるっていうけど、実際影響がどんなもんか分からん
RTTIで起きる速度低下の影響は自前で仮想関数テーブルを用意する場合と同じ。
見栄の問題なのか?w
>>489 見栄だよ
型名保持してポインタを型変換するだけだし
でも使ってない
C++ってゲームプログラミングに使える?
>>491 DirectX使えば、いろいろ綺麗に作れるぞ。
>>492 取り合えず勉強してみます
ありがとう!
キャストは結局のところ「正しくないかもしれないけど見逃してくれ」とコンパイラに指示している。 キャストが正しいことをプログラマーが保証しなければならない。 dynamic_cast(RTTI)もNULLが返る可能性も考えてプログラムを作らなければならない。 どんなにデバッグしても、キャストは客先でプログラムがクラッシュするかもしれない時限爆弾を抱えるようなものである。 暗黙の型変換や仮想関数であれば必ず正しい動作をすることがコンパイラが保証するので堅牢になる。 わずかな設計の見直しでリスクを減らせるんだからキャストは控えるのを勧める。
495 :
デフォルトの名無しさん :2010/03/04(木) 20:22:37
プログラムが正しいかどうかをコンパイラに丸投げする考えのほうがよっぽど危険だよ 第三者たるコンパイラが勘違いしそうな「本当は正しい」ところをマークするのがキャストだ できちゃいけないキャストが通る理不尽な仕様は確かにあるが、それは できることとしていいことの分別がつく人しか C++ を使うべきではないということだ
キャストは影響を局所化してさらに見えないように包めばいいじゃない
>>487 1万回ループさせて0.1秒差とかそんなもん
>>494 NULLが返る可能性を考えないのにdynamic_castを使うとか意味がわからん
そんなの参照と例外に狂ってるやつくらいだろ
暗黙の型変換でプログラムが堅牢になると聞いて
たった10000回で100msも差がでるのか。 100000000回で10msくらいでもまだ遅いのに
>>478 swap以外もすべて明示的特殊化してよい。
暗黙の型変換で堅牢 ハハッ
>>500 ごめん・・・最近なにしても楽しくないし2chで見栄張る位しか生き甲斐がなくて・・・。
もう自衛隊に入るわ。最近政治がアレだし俺みたいなクズ人間は戦争で死んでも誰も悲しまないだろう。
普通にstatic_castしか使わない = Cのキャストでおk static_castでエラーが出るケースなんて,経験でわかるようになる程度じゃろ
>>506 > static_castでエラーが出るケースなんて,経験でわかるようになる程度じゃろ
いや、わからない人用にあるわけじゃないんだけど。
>>506 どんなに経験積んだって人間は間違えるから予防が必要なんだよ
構文が悪い static_cast<int>(var)と(int)varじゃ 後者を使いたくなるのもわかる
>>506 よくないよ。
static_cast 継承関係に無い型をキャストしようとエラーになる
Cスタイルキャスト 継承関係に無い型をキャストしてもエラーにならない。
511 :
デフォルトの名無しさん :2010/03/05(金) 00:31:20
インディアン 嘘つかない
Cスタイルのキャストを残したビャーネが悪い
残すも何も互換性だから
じゃあ完全互換じゃなくしたビャーネはもっと悪い
CとC++って完全互換じゃないの? extern C/C++ とかでなんとかなると思ってたんだけど だれか反例教えちくり
100%の互換となることを目標としたことは一度もない、とプログラミング言語C++に書かれているよ
そうなのか,買って呼んでみるよ
519 :
デフォルトの名無しさん :2010/03/05(金) 01:30:15
int class; この時点から 100% じゃないしな
>>515 変数名に new とか関数名に delete とか、余裕で死ねる。
C89 でもちょこちょこ違うのに、C99 で決定的になったからな<非互換性。 ああ、すべての言語に複合リテラルがあればいいのに。
522 :
デフォルトの名無しさん :2010/03/05(金) 01:47:46
>>521 残念ながら C++ は C89 ではなく K&R C から派生した言語なので
C++ が C89 に対して互換性がないのではなく、
C89 が C++ に対して互換性がないんだよ
C++ 側に「捨てた罪」があるのは K&R C に対してだけなのが原則で
extern "C" などの後付け設定がこの原則の例外
>>522 > 残念ながら C++ は C89 ではなく K&R C から派生した言語なので
はつみみです
ソースある?
D&Eでございます。
それ、禿一人で作ってたころのはなしじゃねーの? 少なくとも ISO C++ が参照してる C は ISO C だし。
526 :
デフォルトの名無しさん :2010/03/05(金) 02:07:38
どのクラスからも呼び出すことの出来る変数はどのように宣言するのでしょうか? staticやexternがあるみたいですが いかんせんエラーが出ます。どうか教えてください
>>522 C++ の設計が K&R C から始まったとして、どうしてそれが
標準 C++ と標準 C との互換性の主従に関係するの?
529 :
デフォルトの名無しさん :2010/03/05(金) 02:15:54
>>528 長いんで省略した形で記述します。
たとえば
==================================
//○×.h
class Cabc : public **
{
省略
public:
//ここでグローバル変数を記述したい
static CString str;
//省略
}
/////////////////////////////////////
○X.cpp
//省略
str = _T("a");
//省略
/////////////////////////////////////
このstrの値を他のクラスで使いたい場合
CString buf;
buf = Cabc::str ;
のようにしてもダメなんでしょうか?
わかりにくくてごめんなさい
なにぶん初心者ですのでよろしくおねがいします
530 :
デフォルトの名無しさん :2010/03/05(金) 02:17:13
>>527 公式に「主従」なんかないだろう
俺は事の経緯から導かれる道義的な関係を指摘したまで
>>515 extern "C"はCとC++の間でグローバルな関数・変数がリンクできるようになるだけ。
構文の解釈が変わるなどといったことは起こらない。
互換でない例としてはvoid*から他のポインタ型の暗黙変換が可能か否かなど。
>>530 いや、導かれてないから。
>>522 の1行目が事実だとしても2行目以降は
あんたが勝手に言ってるだけでしょ。道義的関係とか意味わかんないし。
C89 が当時の標準化もされていなかった C++ と互換性がないとか、当たり前だし。
533 :
デフォルトの名無しさん :2010/03/05(金) 02:36:39
>>532 C89 の目玉が C++ からの逆輸入という事実もあるわな
当時の C++ が標準化がされていようがいまいが C89 はその道を選んだ
どっちが合わせるべき立場にあったかは明確であろう
534 :
デフォルトの名無しさん :2010/03/05(金) 02:37:24
今日は寝落ち
>>533 合わせるべき立場とか、無いから。それ、妄想だから。
その調子で「C++0x は C# に合わせるべき立場にいる」とか
「C++0x は D に合わせるべき立場にいる」言い出すやつが
いたとしたらどう思うよ?
あんたが C++ 大好きなのはわかったが、これはさすがに
言いすぎだろ。
先発のものが後発に合わせるわけにはいかないってだけのことだろ C#がC++0xに対して互換性が無いのと一緒
long longや可変個引数マクロ、数学関数などC99からC++0xへ持ち込まれるものだってある。 初期化リストをC99の複合リテラルと互換性のある構文にしようという提案が出たことだってあった。 CとC++は,お互いに影響を与えつつ受けつつという関係だと思うなぁ。
内部クラスではtemplateが使えないのでしょうか? 以下のようなコードとコンパイルエラーが出ます。 gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) test0.cpp: In function ‘void func()’: test0.cpp:14: error: expected primary-expression before ‘template’ test0.cpp:14: error: expected ‘;’ before ‘template’ test0.cpp:30: error: expected ‘}’ at end of input 12: void func() 13: { 14: template<class T> 15: class Hoge{ 16: public: 17: static void foo( const T& val ){ 18: cout << val << endl; 19: } 20: }; 21: 22: Hoge::foo(); 23: }
使えない。
>>529 > わかりにくくてごめんなさい
わかりにくいのは、エラーが何なのかをキミが隠しているからだ。
人生相談コーナーに「とある良くないことが起きました。どうすればいいですか?」とだけ書いて
送っても、「まぁ、気を落とさずに」みたいな曖昧なアドバイスしか来ないぞ。
542 :
デフォルトの名無しさん :2010/03/05(金) 07:37:28
>>540 えっと、、そこまで難しいことではないんです
ただ、たとえばどんなクラスからでも使えるCStringの変数が欲しいわけ
でそういうのはどうするのか?という質問なんです。
543 :
デフォルトの名無しさん :2010/03/05(金) 07:39:41
>>541 ヘッダで宣言したCStringのつもりです。
このstrをどんなクラスからでも参照可能にするにはどうしたらいいのでしょうか?
とても困っています
よろしくお願いします
ここまで頑としてエラーを書かないのは何でだろうね。 クイズの出題者気取り?
静的メンバ変数でググれ
546 :
デフォルトの名無しさん :2010/03/05(金) 07:50:13
>>544 エラーは
LicenselistViewerList.obj : error LNK2001: 外部シンボル
""public: static class ATL::CStringT<char,class StrTraitMFC_DLL<char,class
ATL::ChTraitsCRT<char> > > CLicenselistViewerList::strrr" (?strrr@CLicenselistViewerList@@2V?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@A)" は未解決です。
です。
俺はただこの問題が解決してほしいだけなのでクイズとかそんなんではないです
本当に困っています
547 :
デフォルトの名無しさん :2010/03/05(金) 07:51:54
>>545 ググって解決できないから頼んでます。
静的メンバ変数だとこのやりかたで宣言したstrは
Cabc::strで外の変数を使えるとあります。
使えません
どうしてでしょうか?
宣言はあってる 定義の仕方が悪い
>>546 エラーメッセージは開発者がなにをすべきか直ぐ分かるようにするために出力してるんだぜ
class名::str;
を.cppの先頭付近にでも書いとけ
デュラララみたいな
>>546 static CString CLicenselistViewerList::strrrという静的メンバ変数の
実体の定義が見つからないのでリンクできないというエラー
静的メンバ変数はヘッダで宣言のみではダメで実体の定義
CString CLicenselistViewerList::strrr;
を.cppファイルに記述する必要がある
553 :
デフォルトの名無しさん :2010/03/05(金) 14:19:52
あのー *x1 += a; ってどういう演算するんですか?
>>553 x1 の指すオブジェクトに a を加えるっぽい。
これ以上は x1, a の型を明らかにしないとわからん。
555 :
デフォルトの名無しさん :2010/03/05(金) 14:28:19
っへー!! てっきり、num1 = a + *x1; とかで何か用意しないとこのaと *x1の合計は作れないものだと思ってました! てことは -=で引き算出来るんですか? ホンマ助かりました。今ポインターの勉強してるんです。 ちなみに問題は最初に点数を指定させて、加算点を入力させるというものです。 やさしいc++第3版 著高橋 をやっていました。回答例に出てきていたので なんぞこれってかんじでした
引き算できるよ。*=,/=もあるし&=,|=,>>=みたいなのもある
557 :
デフォルトの名無しさん :2010/03/05(金) 14:31:29
人の顔のAA二ミエマス。 ホントに貴方紳士ですね!また質問に着ます! 有り難うございました
>>557 名無しさんが一人だとでも思ってるのか?
562 :
561 :2010/03/05(金) 15:51:16
struct a{ virtual ~a{} }; struct b : a{ int array[8] }; //... a *ptr = new b; //... delete ptr; //ptrはa*だけど実際に指しているのはヒープに配置されたbのインスタンス. sizeof(a) != sizeof(b)なのにこんな事してもいいの?
いいよ
全て分かった上で、話題作りで書き込んでる様に見えるんだが そりゃ解体子が仮想だから
>>565 destructorがvirtualかどうかは関係ないでしょ?
>>563 newしたときのサイズがどこかにしまってあるから。
568 :
563 :2010/03/05(金) 16:30:00
解体子っていうのはクラス内部のリソースを開放したりするためのもので、 自身がヒープに配置されていたり、それのメモリ管理は関係ないような認識でした。 事実、インスタンスがスタックに配置されていてもデストラクタは走ります。 これは、インスタンスのメモリ管理はインスタンスを抱えているスコープが管理するべきだという事です。 曖昧な理解が解消して助かりました。ありがとうございます。
Java厨は勉強熱心だなぁ それにくらべてC++erは・・・
JavaとC++の両刀使いの人っている?
ASもJSもPerlもRubyもEsolangも普通にやるがね
563は納得したのだろうか。 確保した領域の大きさについてだけ言えば566が正しいと思う。 確保した自由記憶領域の大きさはOS(システムコール)が記録している。 解放する時に大きさを知っている必要は無い。 p = malloc( N ) の後 free( p ) だけでいい(Nを指定する必要が無い) のと同じ。 そういう意味では565は見当外れ。 まぁC++スレだし、そういうことを訊きたい訳じゃないんだろうけど
ポインタを整数サイズで-1して整数表現で取り出したらサイズだったなんてことはよくある事
上のシンプルな例ならともかく多重継承なら死にかねない
copy(vec.begin(),vec.end(),ostream_iterator<T>(cout,"#")); だと最後にもセパレータが入って 1#2#3# となってしまいますが、 1#2#3 がたいてい欲しいものだと思います。 whileの内で条件分岐させる以外にうまい方法知りませんか?
最後の一つ前までやればいいだけにみえる
>>577 --vec.end()
なんて怖すぎます!
・・・ブルブル。
ランダムアクセスイテレータならcontainer.end() - 1でいいだろ
怖くねーよカス
あれ、空のときに困ると思ったんだけど、 やってみたら大丈夫だった・・・?!
あ、わかった。 要素が一個だけのとき、何も出力されなくなる。
いや、そもそもぜんぜんダメだ。 v=[3,4] のとき、出力が 3# ですよ。。。
>>583 やっぱそっちですか。
イテレータとかすぐに書けないけど・・・。
ありがとうございます。
boostはホント何でもありますね・・・。
なるべく依存したくないけど。
>>583 理解できたので、ほとんどそのまま使いまわせそうです。
たいへん助かりました。
>>587 boostでテクニック勉強したら、自分でサブセットなライブラリを作れば依存しなくてすむんじゃないかな。
Hoge Hoge::getObj( ){ return *this; } Hoge& Hoge::getObj( ){ return *this; } return *this はそのままで戻り値の書き方次第(Hoge& or Hoge)で 参照返しとオブジェクトのコピー返しと変わってしまうというのに違和感を感じる。 上の2通りの違いを *this の部分でも書き示す方(例:参照返し→ @*this )が良かったのに、と思ってしまうのですが どうですか? (どうですか?、って言っても仕様だからどうかなる話ではないのですが)
それが気になる人は、それ以上に、関数を呼び出すほうも気になるだろうね。 int func1(const Hoge& h); int func2(Hoge h); Hoge hoge; func1(hoge); func2(hoge); // 同じ書き方 関数定義を書いている時は、すぐそこに戻り値の扱いが見えてる安心感があってまだいいけど、 関数呼び出しを書いている時は、関数の宣言or定義がよその何処かに書かれてる。 エディタ支援があるとはいえ、「遠くの何かを知ってなきゃいけない」感じがあって、より落ち着かないのでは。
constなら区別して呼び出せるけどね void foo(int& a); void foo(const int& a); int a; //constではない foo(const_cast<const int&>(a)); //ここはconst版を呼びたい
関数宣言見ただけじゃ参照かどうかわからなくて困るだろ と思ったけど int &a = @b; みたいにしてほしいってことなのかな
constにするときはstatic_castでいいんじゃないか
そんなことよりint @sp = spnew int [10]; int $wp = wpnew sp;を組み込んでくれ
シンタックスシュガーは もっと多くてもいい
オレサマプリプロセッサ作って好きに構文創作しれ
>>597 #define amigo friend;
愛用してます
フレンド程度に内面を洗いざらいさらしていいのか?
>>597 #define foreach BOOST_FOREACH
>>599 friendのおかげで、余計なpublicを作らずprivateで済ませられるんじゃないのか。
#define buddy friend; じゃないの?
friendはクラステンプレート中にテンプレート関数を定義したい 時に、暗黙の型変換ができるように使っている。 Effective C++で紹介されていた内容。
>>598 ほらみろよく判って無い奴が調子に乗って暴れ出したじゃないか
そこは指摘せずにそっとしておく所だろ
abort() if (!p); みたいに書けるようにはならんのか。
if (!p) abort() ;
>>606 C++などのほかの言語なんかに手を出さず、一生perlを使い続けるべきだと思います。
perlではif文を後に書くのか?
>>596 言語の文法は最小限でライブラリで拡張できるほうがいい。
611 :
598 :2010/03/06(土) 18:17:05
すいません嘘です
abort() if(!p) else exit(); とか普通に書きたいんじゃないの?
>609 文修飾子という扱いで後ろにも置ける。 if(e) { func(); } func() if e; は OK だけど、 if(e) func(); { func() } if e; はできない。
614 :
デフォルトの名無しさん :2010/03/06(土) 20:00:36
>>613 2種類の書き方があるっていうか、そういうのって分りにくくないのかな?
後に書くということは
func(すっげー長い式なんたらかんたらどうのこうの) if e;
だと読むときifを読み落としそうだなあ。
ワケ分からんw C++だと、func() ;も{ func() ; }も、ひとつのstatementなので、ものすごい違和感があるな。 { func() ; } if e ; ができないというのは、ものすごく違和感があるな。
struct A; struct B{ B( A& ); } A a(); // これとか B b( A() ); //これが 関数宣言にみなされない書き方ないの? A a; B b( a ); とかじゃない方法で。
>>615 思うに。
{
すげーー長い文
なんたらかんたら
だらだらだらだら
}
if e;
って読むのに困るよね。
do{}while()でも読みにくいのね。
do... whileは、まだ、先頭にdoがあるから、「あ、これはdo... while文の始まりだな」と分かるわけで、 それほど読みにくいってほどでもないんじゃないかな。
func() if e; はシンタックスシュガーの一例か? 混乱の割にメリットは感じられない。
ループの先頭などで、 break if foo continue if bar とかするのは気持ちいい。
だから、perl以外の言語は触らずに perlだけ使ってなよ。
ハ,,ハ
(*゚ω゚ )
>>622 お断りします。Rubyも使います。
. (=====)
_(_⌒) )
/\ `J  ̄ ̄\
 ̄ ̄ ̄ ̄| | ̄ ̄ ̄
|
/ \
 ̄ ̄
perlで俺シンタックスシュガープリプロセッサ作ればいいんじゃね?
foreach(int x, std::make_pair(v.begin(), it)) みたいにカンマが含まれても大丈夫なマクロが欲しいです
>614 Perl には TMTOWTDI(There's More Than One Way To Do It:やり方は一つじゃない)という スローガンがあってな。 >615 Perl では { } は block であって文じゃないんだ。 >620 if (e) func(); ができなくていちいち block 書くのが面倒という事なんだと思う。
あの、ひとついいですか? 僕は現在高校2年生です。そんなぼくにもC++はマスター できます?
それなりのことはできるようになりますがマスターはそう簡単にはできません
>>625 C99の__VA_ARGS__が、C++0xに入る。
double* darray = new double[0]; delete [] darray; のようなことがプログラム中で起こるのですが、問題ありますか?
サイズ0だと続けて次に確保したときに、おんなじ場所を確保しちゃうような気がする ダミーで1byteぐらい確保されんのかな
>>634 ヌルを返したり他のオブジェクトと同じアドレスを返したりしちゃいけないことになってるから、
だいたいの実装がそんな感じ。
0バイトのオブジェクトは存在できないから標準に従えば1バイト以上確保することになる だがdarray[0]にアクセスすると未定義動作 変なの
void *operator new (std::size_t size) { if(size == 0) throw std::bad_alloc("Fack you!"); return std::malloc(size); }
error: no matching function for call to 'std::bad_alloc::bad_alloc(const char [10])'
"C++"で、依存関係を解決するためにインターフェイス指向な設計に取り入れるってこと多いかなぁ? テンプレートではなく、仮想関数を使う方法で。
s/設計に/設計を/
>>639 あると思うよ。
今の時代だとクリティカルな部分さえ最適化できればいいから動的型付けに対してそんなに神経質になる必要も無い。
ソフトウェア工学から見たある程度の規模からの開発のし易さや動的な依存関係の解決には仮想関数が向いているし
テンプレートを用いた静的な型レベルの解決なら実行速度に対する最適化が向いている。
臨機応変に適材適所できるからC++が選ばれる、何てこともあるね。
強い動的型付けな言語(Rubyとか)になっちゃうと融通が利かないし。
でもRubyとかを採用する現場では速度低下の弊害より人材のコスト考えてる場合ばおおいね
>>639 俺はよく使ってる。
継承を使う時は、純粋仮想関数のみで構成されたクラスの継承がほとんど。
テンプレートを依存関係を解決するために使うのは、本当にテンプレートが効果的かよく考えてやった方がいいと思う。
>>634 コンストラクタで malloc() を呼ぶと
malloc(0) でも8バイトぐらいは確保される。
ここらへんは Cライブラリの実装次第だが、
あとで realloc()/free() に渡す可能性があるポインタということを
考えると0バイトであってもユニークなポインタが返されるべき。
templateを使った依存関係の解決ってどういうの?
>>644 class Hoge {
void foo() { fuga_.(this); }
Fuga<Hoge> fuga_;
}
俺はこんなのを想像した。これは相互参照か?
単に特定のクラスに依存したら拡張性がなくなるから、テンプレート引数で指定できるようにしたいという事かもしれない。
646 :
645 :2010/03/07(日) 12:22:14
2行目訂正 void foo() { fuga_.bar(this); }
こういうのを相互参照って言うんじゃないか class b; class a { b* bb; }; class b { a* aa; };
多態性を持ちつつどこかに保存しなければならない場合にはインターフェース(か、型消去)を使うかな でも保存する必要が無い関数の引数とかだったらテンプレートの方がいいと思う 例えば標準のアルゴリズムをテンプレートじゃなくてインターフェースで解決しようとしたら結構めんどくさいだろう std::random_access_iterator_interfaceみたいなのが沢山作られて、それを適切に継承してないイテレータは対応アルゴリズムが使えない みたいな感じで、行儀はいいんだけど、すごいめんどくさくなる
理想的には継承と多相は独立した概念なんでしょうね。 要求される振る舞いが出来ることを保証する仕組みの一つが 継承であるだけで。
いわゆるダックタイピング
ダックタイピングはコンセプトがあればなぁ
せめてコンパイラのエラーメッセージがわかりやすくなれば
スマポのお勉強してるんですが キャストってどうやって実装してるんでしょうか? class hoge : public fuga; void test(const oreore::unique_ptr<fuga> &p); oreore::unique_ptr<hoge> p(new hoge); test(p); といった感じの使い方を許可したいんですがどうにもうまくいきません 所有権の移動を禁止する方針で作っている(コピー代入を封印)のでキャストするときにテンポラリな値を返せません template <class Other> oreore::unique_ptr<Other> (void) { return oreore::unique_ptr<Other>(*this); // 禁止されてる }
>>654 C++0xなら、rvalue referenceが使える。
それ以前のC++では、一応、auto_ptrを実装できるぐらいの方法はあるが、
そのテクニックを学ぶことは、精神衛生上よろしくないので、おすすめしない。
657 :
デフォルトの名無しさん :2010/03/08(月) 04:21:56
>>654 コピー代入を封じるなら無理。
キャストは、元オブジェクトからキャスト先オブジェクトという作るという点では、複製に等しいため。
それこそ
>>655 の言うように所有権の移動を許可する方向でやるしかない。
(もちろん所有権が移る以上、本来のキャストとは若干異なるセマンティクスになる)
const_cast ってconstはずしだから <> の中に型書くの無駄だなぁって思ってしまう。 const int* からconstとったら int* に決まってんじゃん、と。
>>658 const_castがオマエの言うような機能だったとして、このコードはどうすればいいんだ?
int x = 0 ;
int const * const p = &x ;
const_cast(p) ;
さあどれだ?
const_cast<int * const>(p) ;
const_cast<int const * const>(p) ;
const_cast<int *>(p) ;
template<class vtype> class Test { public: Test( ){ } void func( ); }; のようなクラスのとき、 vtype が P と Test<P> (Pはプリミティブ型) とで呼び出す func( ) を変える方法はありますか?
特殊化すればいいよ
662 :
660 :2010/03/08(月) 12:15:01
>>661 このようにしたのですが、うまく行きません。。。
template<class vtype>
void Test<vtype>::func( )
{
cout << "aaa" << endl;
}
template<class vtype>
void Test<Test<vtype> >::func( )
{
cout << "bbb" << endl;
}
664 :
660 :2010/03/08(月) 12:39:43
>>663 ありがとうございます。
クラスレベルで特殊化してしまうと、メンバ関数が沢山ある場合
同じようなコードが沢山生まれてしまうので
関数部分だけ特殊化できれば、と思ったのですが
クラスのところで特殊化しなきゃダメなのですね。
666 :
660 :2010/03/08(月) 12:52:05
>>665 テンプレートと継承の組み合わせというのは考えられませんでした。
ありがとうございます。
>>655-657 サンクスです
キャスト≒複製って知りませんでした
時期標準のソースをチラ見したところ標準もキャストはサポートされてなかったので、uniqueの方はキャスト諦めることにしました
構造体のメンバ変数を一括で代入する方法ってないんですか? 例えば構造体Aの変数のメンバ変数を全て0にするとか…
struct S { int a, b, c; double x, y, z; static S empty; }; S S::empty = { 0 }; S var; var = S::empty;
サンクス。クラス使わないとダメなんすか?
pod作る関数を作ればいい。テンプレートで
struct S { int a, b, c; double x, y, z;}; S a={0}; これで事足りるんじゃ
あーざっす
初期化だ(キリッ
>>659 const_cast<int *>(p)だろ
他のconstが必要なら後で付ければいい
何があかんのですか
const const_iterator* it; const_cast(it) これはどうなるんだ? const_iteratorはポインタかもしれないしクラスかもしれない
const_iteratorがconst Type*だった場合、 itの型はconst Type *constでconst_castするとconst Type*になる。 そうでない場合、const_castするとconst_iteratorになる。ただそれだけの話。
>>676 void const * const * const cpcpc = 0;
void ** pp = const_cast<void**>(cpcpc);
void const ** cpp = const_cast<void const**>(pp); // このcastはどうすんの?
>>678 >itの型はconst Type *constでconst_castするとconst Type*になる。
なんでType*じゃないんだ?
>>676 と矛盾しない?
std::complexのconj( )って何でメンバ関数ではなくグローバル関数なのですか?
無闇にメンバ関数にするとprivateにアクセス出来てしまうから、 privateにアクセスする必要のない関数は メンバでもfriendでもない関数にするのが良いって 偉い人が言ってた
683 :
681 :2010/03/08(月) 22:28:24
>>682 ありがとうございます。
もし自分がcomplex作ったら、conj( )をメンバ関数にして
privateなデータを変更してしまうように実装しそうなのですが
これは良くないんですかね?
そもそも変更することがおかしいんじゃないかい。 メンバ変数にするにしてもconstにするべきだと思う。 共役複素数を求めるだけだよね?
むしろその程度の軽い型なら不変型にしちゃった方が
686 :
681 :2010/03/08(月) 23:02:53
>>684 イメージ的にはこんな感じです。
myComplex<double> mc0(2,2); // 2+2i
mc0.conj( ); // 2-2i
グローバル関数にするとコピーが発生してしまうので
良くないのかなぁ、と思ったのですが。
実測した訳じゃないが、 あまり効果なさそうな気はする。 コードを見やすくしたほうがいいんじゃないだろうか。
なんで配列はイニシャライザリストで初期化出来ないんですか?
C++0xにご期待ください
>>679 const増やすのはstatic_castでもreinterpret_castでも出来る
お好きな方で
>>676 void f(void const* a[]); // const 一個付け忘れてるけど変更できない外部ライブラリ
void f(void* a[]); // 同上、ただし非 const データを対象とするオーバーロード
// ここから自前のコード
void g(void const* const a[])
{
f(const_cast(a)); // 上のオーバーロードに渡したいのに下のほうにいっちゃう
}
こわくね?
まあconst_cast使うなってのが基本だから それを書きやすくするうえに他のキャストと違う形になる 省略記法なんて認められないと思われる
>>690-691 うちのVC++2008EEではconst_castかC style castでないと通らないんだけど、
なんかおかしいのかな。
どうせ<>書いてないとか
void ** const cpp = static_cast<void **>(pp); えっ?
>>696 それは、規格の文面によって、明示的に禁止されている。
4.4 Qualification conversions [conv.qual]
なぜできないのかというと、それを用いることによって、const性に穴が生じるから。
規格のサンプルコードを、適当にコメントを補って引用すると、
int main() {
const char c = ’c’;
char* pc;
const char** pcc = &pc; // 仮に、これが許可されているとする
*pcc = &c;// ppcを介して、pcを変更している。
*pc = ’C’; // pcはconstでもないのに、constなはずのcを参照出来ているので、変更できる。
}
つまり、constなppcを介して、非constなpcを変更できてしまうので、
pcが、明示的なキャストもなしに、constなオブジェクトを参照することが可能になってしまう。
>>698 規格の参照までしていただいて、ありがとうございます。
参考になります。
ということで、これを踏まえて改めて
>>679
ubuntu の gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) 環境で例外クラスの実装を見ようと思ったのですが /usr/include/c++/4.4/stdexcept に logic_error などの宣言はあるのに実装が書いてありません。 どのファイルを見たら良いでしょうか?
const_castの話してるやつはコテ着けるか 婉曲表現と皮肉をやめて直接主張しろ 何人かいて訳が分からない
はがす時は全はがしが楽じゃね?ってことが基点となっていると思うので void const * const * const cpcpc = 0; void ** pp = const_cast<>(cpcpc); // 全はがし void const ** cpp = const_cast<void const**>(pp); // つける時は書く // void const ** cpp = const_cast<void const**>(cpcpc); // 一部はがしのときもこれまで同様書ける というのを望んでんのかも
がんばれ 658 :デフォルトの名無しさん :2010/03/08(月) 07:36:01 const_cast ってconstはずしだから <> の中に型書くの無駄だなぁって思ってしまう。 const int* からconstとったら int* に決まってんじゃん、と。
constの話で盛り上ってるからついでに聞きたいんだけど struct X { int *p; void test(int x) const { *p = x; } }; こう書くとconst指定してるのにオブジェクトの内容が変化してる これって合法なの?
>>704 Xのオブジェクトはpであることを思い出せ。
pはint*型だから「int型の値のあるメモリの位置」を指している。
*p = xは「pの指している先のint型の値に対する副作用」であって「pに対する副作用」ではない。
pは宝の地図 *pは宝の中身 Xのメンバはpつまり宝の地図 だからtest(int x) constとは宝の地図を書き換えちゃいけないってこと *p = xは宝の中身を入れ替えているだけ
中々面白い例え方をするな。
**pは宝の地図の在り処を書いた地図か。判りやすいね。
ゲームのお使いクエストだな。 そのお宝の例えは俺は結構好きだな。
へー、いい表現じゃん
サンクス 正常な動作だったのね
new intは新しく宝を作るが、この式自体は新しく作られた宝のありかを示す地図を返す。 new int*は宝の地図を新しく作りその地図のありかを返す式だが、新しく作られた宝の地図には宝のありかは書いてない。 難しいな。
new int*なんてあんの? あるなら知らなかった。
型なら何でもnew出来るだろ
関数型もできるっけ? 関数ポインタじゃなくて。
716 :
706 :2010/03/09(火) 21:01:33
何の気無しに書いたんで、反応あって驚いてる。
>>706 は、一番最初にポインタを勉強する時に俺が(たまたま)イメージしたもので、
今にして思うと、地図という「質量を持った物体」でポインタを喩えたのが好都合だった気がする。
たまたまそういうイメージをしたお陰で、ポインタもまた「そういう値」である、って所で
まったく混乱せずに済んだ。
>>708 が言うように、ポインタのポインタも
「勇者は宝箱を開けた。なんと宝の地図を見つけた!」ということだと考えれば楽だったし。
C++は勉強するほど自信がなくなっていくな・・・boostマジキチ
>>716 初心者には分かりやすい言い例えだね。
俺もそれ使わせてもらいます。
住所とか例えるより絶対わかりやすい。
>「勇者は宝箱を開けた。なんと宝の地図を見つけた!」 あるあるw
721 :
デフォルトの名無しさん :2010/03/09(火) 23:38:31
ポインタを宝箱に例えるなら、中身の種類は開ける前から判っているんだが
722 :
デフォルトの名無しさん :2010/03/09(火) 23:38:54
s/宝箱/宝箱の地図/
で?
ヌルポインタはミミックだな 開けると死ぬ
住所にたとえるのと変わらんと思うがね
ていうか別に喩えなくても分かるから
727 :
デフォルトの名無しさん :2010/03/10(水) 01:46:56
ミミックは固定ボスだから、地図が読めない奴が初見殺しされるだけだろ
minorという変数がプログラム中にありますが、 cstdlibをインクルードしたら以下のようなエラーが出るようになりました。 error: macro "minor" passed 2 arguments, but takes just 1 これは単純に、minorという変数名を使うな、という解釈でよいでしょうか?
>>728 どう読んだらそんな解釈になるんだよ。
そのエラーが再現する最小ソースを作ってみれ。
730 :
728 :2010/03/10(水) 05:25:53
>>729 言葉足らずでした。
上記のエラーは、
ctdlib の中(もしくはcstdlibがインクルードしているファイルの中)に
引数を1つとるminorというマクロ(?)があるから、
引数が2つある自作クラスのオブジェクト名をminorにしてはいけない
ということでしょうか?
以下ソース
#include <cstdlib>
class Hoge
{
public:
Hoge( int i, int j ){ }
};
int main(int argc, char* argv[])
{
Hoge minor(1,1);
return 0;
}
>>730 別に言葉足らずじゃない。
>>729 が寝ぼけてるだけ。
環境によってはsys/types.hにminorマクロがあるので使わない方がいい。
>>730 手元の Cygwin g++ 4.3.4 では何事もなくコンパイルが通ったよ。
ちなみに >728 の環境(OS、コンパイラ、そのバージョン)は何?
>>731 cstdlib のインクルードでユーザーが使える名前がマクロ定義されてるのは
コンパイラのバグ(標準違反)だと言ってしまっていいと思うんだけど、そういう
予防しとかないといけないものなの?どっかの環境での常識?
735 :
728 :2010/03/10(水) 06:04:13
>>733 Ubuntu 9.10
gcc version 4.4.1
です。
gcc -v の内容全部貼ると
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v
--with-pkgversion='Ubuntu 4.4.1-4ubuntu9'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4
--enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic
--enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu
--target=i486-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
-std=c++98 とかすれば逃げれたりするんじゃないかなー。 まぁ #undef すりゃいいんだけどね。
737 :
728 :2010/03/10(水) 06:35:01
以下のソースコードコンパイルすると
#include <cstdlib>
void minor( int i, int j )
{
}
int main(int argc, char* argv[])
{
return 0;
}
test.cpp:5:26: error: macro "minor" passed 2 arguments, but takes just 1
test.cpp:5: error: variable or field ‘minor’ declared void
test.cpp:5: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
というerrorと、warningが出ます。
>>730 のソースコードではwarning出ませんでした。
functionってすげいな ソース眺めるだけで勉強になる
struct A; struct B{A a;}; struct A{int a;}; int main(){return 0;} 前方宣言したら、後で定義してれば 使えると思ってたんですが これがエラーになります Bの中をA* aにするとエラーが消えるのですが その辺に理由があるんでしょうか?
ちょっと実験してみたところ、前方宣言って思ったほど強くない?んですね Aのデータは定義されるまでは全く参照出来ないのか struct A; struct B{void f(A *a){}}; //セーフ //struct B{void f(A& a){}}; //セーフ //struct B{void f(A a){}}; //アウト //struct B{void f(A& a){a.a;}}; //アウト //struct B{void f(A* a){a->a;}}; //アウト struct A{int a;}; int main(){return 0;}
サイズがわかってるかどうかで判断できるよ
なるほど、セーフなのはアドレスですもんね ありがとうございました
>>738 しかしそんなソースを仕事で書いたら
同僚に白い目で見られそうだww
すみません vectorのresizeでサイズを大きくした時に 拡張した結果メモリの再配置が起こったとすると resizeする前のデータはコピーされるのでしょうか?
ざれます
ありがとうございます><.
クラスを使ってプログラミングする場合、main関数はどのように使用すればいいのでしょうか?
普通に使用すればいいです Javaみたいにどっかのクラスのstatic関数にする必要はなし、というか無理
オペレータオーバーロードの ->* って、どう定義してどう使うんですか? ググール先生に聞こうと思ったんだけど記号検索できませんでした
結合力最強の二項演算子なので マクロとかで細工するときに便利なこともあります
>>751 どうもです
しかしなんだこれって感じですね
ポインタエミュレートのために
(myp_hoge->*(&MyPtr<hoge>::Func))(a, b, c);
といった形で使いたいんですが、定義の仕方が分からないです(->なら簡単なんですが・・・)
>>752 そういう特殊な使い方ってよく思いつくもんですよね
>>748 徹底したクラス指向で行くならこの程度のものになる。
int main()
{
MainClass m;
return m.main();
}
int main() { return MainClass()(); } 徹底するならこうだろーと思った俺はそろそろ寝るべきか
operator RESULT(); //用意するだろ普通
throwでint投げると問題があるようなことを聞いたのですが、 どんな問題があるんでしょうか? ポインタでキャッチしてしまうとか?
受け取る方はみんなstd::exceptionを継承してて欲しいなーって思ってるから
なるほど。よくわかりました。
istringstream の putback って何回でも呼んでおk?
boost::functionとstd::functionって混在しても問題ありませんか? それともどちらか一方にすべきでしょうか?
混在させたこと無いからわからんけど、大丈夫じゃね? どっちも最終的にはただの関数オブジェクトになるわけだから boostのほうにstdのfunctionを代入することも逆もできるはず 名前は名前空間があるからかぶるわけないし
ABI互換性は?
混在といっても、ひとつのコンパイラでコンパイルするんだからABI関係なくね?
namespace boost = std ;
ありがとうございます。 今のところはboostが使えるならboostが無難かと 思うのでboostにします。
>>766 えぇーーー
普通は逆でしょ
標準で済むなら標準を使うのが筋でしょ
>>767 std::function はまだ標準じゃないでしょ。
769 :
767 :2010/03/11(木) 23:40:20
>>768 そりゃそうだ
boost と std だけ見て function を見てなかったよ
placement newを使わずに、任意のメモリ領域にコンストラクタを呼ぶことは不可能?
>>771 何がしたいのかわからないけど、コピーでいいなら std::allocator::construct() とか
std::uninitialized_copy() とかが使えるんじゃない?
template <class T> void Caller( T &f ){ f(); } に対して、 void Callee(); があり、 Caller( Callee ); // これだとコンパイルが通るのに、 Caller( &Callee ); // こっちは通らない のはなぜですか?
関数の引数に配列の参照を渡したいんですが、どうすればいいですか
>>774 サンクスです。
T &fは「関数の参照型」と言えばいいんでしょうか?
また、関数ポインタを呼ぶ際は、
(*f)(); //デリファレンスあり
f();//なし
2通りで呼べますが、これはシンタックスシュガー的なものですか?
どっち使ってもOKですか?
template<typename T, size_t N> void func(T (&x)[N])
typedef std::deque<int>::iterator iterator; iterator tekitou; //... tekitou == iterator(); //tekitouに代入処理がなかったらtrue を期待して組んでたら例外が発生してパソコンが爆発したんですけど tekitouがデフォルトコンストラクタ走ったまま何も触られて無いかどうかを判定する方法はありませんか?
>>778 パソコンが爆発するプログラムを作っているんだったら
いますぐやめなさい。
パソコンが爆発するプログラムを作っているのではありません。 パソコンが爆発するのを防ぐプログラムを作っているのです。
781 :
デフォルトの名無しさん :2010/03/13(土) 01:15:50
爆発させるプログラムにも実に巧妙なメカニズムがあってだな・・・
兎に角、例外が発生してプログラムが正常に動作しないと爆発を防ぐ事ができないのです。 ご教示いただけないでしょうか?
判定する方法は無い ポインタと違ってイテレータにはNULL入れられないからねぇ int *ptr = 0;
本当に爆発するというなら、 本題なんてどーでもよくて、爆発させる方法を知りたい気すらする。
bool変数でも使って対処しとけ
std::pair<iterator, param>ってしてたけどSTLがクソ過ぎてstd::pair<std::pair<iterator, bool>, param>って書かなきゃいけなくなったわ・・・
こういうときは boost::optional だっけ?
つtuple
end()をNULL代わりにしたらあかんの?
今回もそうでしたが、コンテナを特定できないとそれは使えません。
じゃあNULL用の適当なコンテナ作ればいいじゃん
std::pair<iterator, param>ってしてたけどSTLがクソ過ぎてstd::pair<std::pair<iterator, dummy_container>, param>って書かなきゃいけなくなったわ・・・
nil使えよ
iteratorがコンテナと関連付けられてるかチェックしたいってことなのかな? わざわざややこしいことやってるように見えるけど
namespace boost { namespace detail { struct none_helper{}; } typedef int detail::none_helper::*none_t ; } // namespace boost namespace boost { none_t const none = ((none_t)0) ; } // namespace boost このコードはいったい何をしようとしてるわけ?
ググった?
>>795 他のどんな型からも自動変換されないし、
他のどんな型へも自動変換されないような変数を定義してるんじゃね?
俺のPCは蒸着するぜ0.05秒で。
手荷物どころかそのうち航空貨物での取り扱いも断られる
そして単純所持禁止へ
コンピュータが爆発するって 昔の映画や漫画によくあったな
「映画の中のコンピュータ」って ジョークがあったな
「なお、このPCは自動的に消滅する」
>>799 あれってさリュック背負ってたりするとセムシ形状に成ったりするん?
pointer to memberって使ったことあんましないからわからんけど ほかのpointer to memberじゃないとキャストできない(void *にreinterしても変換できなかった)から他の型と比較できない なおかつメンバが空だからnullしか入れるものがない したがってただひとつの状態を持てるってことかな C++ってこういう気持ち悪いバッドノウハウ多すぎるよね すなおに仕様でnil型導入すればいいのに
一般的な実装上の都合からいうと、 メンバへのポインターは、単なるオフセットに過ぎない。
null_ptrをお待ちください
>>807 実装上の都合を言語ユーザに押し付けてる感はあるな
ごめん、途中で送信してしまった。
>>810 他の言語はともかく、
余計なオーバーヘッドを嫌うC++なら、こういう制限も許される(むしろ歓迎される?)よね。
>>810 型変換については妥当な話だと思うし、 nil の不在は実装上の都合ではないだろうし、
何のことを言ってるの?
void Test(int *array) { // ごにょごにょ(配列の長さについては考えないとする) } みたいな関数があったとき、 int array[3] = {0,0,0}; Test(array); はコンパイルできるのに、 Test({0,0,0}); はコンパイルできない。 配列に付ける名前が不足しちゃうのでなんとか名前を付けずにやりたいんだけど、 良い手段ない? それともなんでもいいからとりあえず名前を付けざるを得ないんだろうか。
名前付けないと可読性下がりそう
>>814 C++0x をお待ちください。
名前が不足するとかいうのがよくわからんが、マクロでスコープきったり、必要なら
__LINE__ あたりとくっつけとけばよかったりしない?
C++0x 全部じゃなくても、 gcc みたいに C99 の機能が取り込まれてるコンパイラなら
↓こんなのが使えたり。
void Test(int *array);
#define TEST(...) do { int array[] = __VA_ARGS__; Test(array); } while(0)
void Tests()
{
TEST({1,2,3});
TEST({4,5,6});
TEST({7,8,9});
}
可変長引数マクロ関数使えるのか
>>814 ヘルパー関数を使って、
std::vector<int> make_vector(int num, ...);
Test(&make_vector(3,0,0,0)[0]);
とか、
Test((int*)"\x00\x00\x00\x00""\x00\x00\x00\x00""\x00\x00\x00\x00""\x00\x00\x00\x00");
などの悪手しか思いつかない。
配列リテラルとかLL出身者っぽい要望だなぁ
>>816 レスありがとうございます。
> 名前が不足するというのがよくわからん
Testを沢山呼ぶんですよ。
それで、
int array1[3] = {0,0,0};
Test(array1);
int array2[3] = {0,0,1};
Test(array1);
int array3[3] = {0,0,2};
Test(array1);
以下大量に。
(実際は配列の中身はもっとぐしゃぐしゃで、規則性はないデータになる)
__LINE__をつけるというのはいいですね。
>>818 レスありがとうございます。
STL不勉強のためすみませんが今はちょっとよくわかりません。
>>819 はい・・・LL出身です・・・。
とりあえず__LINE__くっつける方法で行きたいと思います。ありがとうございました。
>>820 なんかTestの引数が全部array1になっちゃってますが、
2回目はarray2、3回目はarray3です・・・。
C99にはズバリの機能(複合リテラル)があるのだが、C++0xに入るとは聞いていない。 Test((int[]){0,0,0});
二次元配列にすればいいだけなんじゃない int arys[100][3]; for(int i=0;i<100;++i){ arys[i][0]=0; arys[i][1]=0; arys[i][2]=i; test(arys[i]); }
>>822 std::initializer_listが入る
825 :
814 :2010/03/13(土) 21:41:00
>>823 >>820 でちょこっと書きましたが、実際には配列のデータはもっとぐしゃぐしゃで、
必ずしも
arys[i][0]=0;
arys[i][1]=0;
arys[i][2]=i;
となるわけではないのです。
質問のために簡略化しているので・・・すみません。
それなら読み込めばいいんでは? int arys[100][3]; for(int i=0;i<100;++i){ cin >> arys[i][0] >> arys[i][1] >> arys[i][2]; test(arys[i]); } これは標準入力だけど、別にファイルからでもいいし
827 :
814 :2010/03/13(土) 21:50:09
>>826 そうした方がいいでしょうかね・・・大量のデータをソースコードにべた書きするのは
よくないかなぁと思ったんですが、
データをあまり見られたくないんですよ。
それで、別ファイルにするよりはソースコードに埋め込んだほうがどちらかというと
見られにくいかなぁと思ったので。
別にソースに埋め込んでも見ようとすれば見れるのでなんてことはないんですが。
慣れたLLでコードジェネレートしればいいじゃない
829 :
814 :2010/03/13(土) 21:57:51
>>828 なるほど、考えてみます。ありがとうございます。
831 :
814 :2010/03/13(土) 22:02:11
>>830 Visual C++ 2008なので使えると思います。
考えてみます。
>>820 int *arrays[] = {
{ 0,0,0 },
{ 0,0,1 },
{ 0,0,2 }
};
みたいなのじゃダメなの?
argv と同じやりかた。
めんどくせw
>>816 __LINE__とくっつけたとして、どうやって参照するの?同じ行が前提?
>>835 同じ行に書くか、ひとつのマクロ内であれば問題なく使えるでしょ。
この場合は単にスコープ分けるだけでも済みそうだし、
__VA_ARGS__ が使えるなら >816 のやつがいいと思う。
つーか規則性の無いグシャグシャなデータにしたのがそもそも間違いだろ。なんで誰も突っ込まないんだよ データってのは規則正しい形式なのが当たり前で、規則正しいからこそコードを簡潔に記述できるんだよ struct Recode { int num[5]; char str[80]; }; Recode recodes[N] = { {〜}, {〜}, }; for(int i = 0; i < N; ++i) Test(recodes[i]); こんな感じに書くのが基本に忠実な答え まずはデータ形式から見直そう
>>837 int の配列って言ってるだろ。十分なデータ構造じゃないか。
規則性がなくてぐしゃぐしゃなのは配列の中の値だろ。
(データ長+データ実体)*nを1次元配列で持つとか
質問のために簡略化してるって構造のことじゃなくて値のことだったのか? だったら二次元配列を使おう、でおしまいだね。いったい何を悩んでるんだろう
841 :
814 :2010/03/13(土) 23:52:42
Visual C++ 2008ってC99は未だっぽいようです・・・
つまり複合リテラル
>>822 も可変長引数マクロ関数
>>816 も無理のようです。
>>840 構造も、値も、です。
>>814 にかいたTestは実際はオブジェクトのコンストラクタなのですが、これの定義は
CTest::CTest(int Id, const char* Name, const char* Species, const char *Sex, int* Hp_max, int* Attack, int* Speed)
: (メンバ初期化リスト省略) {}
と、
>>814 で挙げました配列は3つ、さらに文字列や整数値が引数にあります。
で、これのインスタンスを5個ほど作る処理を書きたいのです。
多次元配列を用いようとすると、Hp_maxとAttack、Speedをまとめて記述し、IdやName,Speciesなどの値と離れて記述する
ことになります。できればインスタンス毎にまとめておきたいのですが・・・
実際にどう記述してるのか分からん
843 :
814 :2010/03/14(日) 00:09:58
一応締切?とさせていただきます。 レスを頂いた皆さま、大変参考になりました。ありがとうございました。
>>841 じゃあ
struct X {
int Id;
const char* Name;
const char* Species;
const char* Sex;
int Hp_max[N];
int Attack[M];
int Speed[O];
};
X xs[] = {
{1, "a", "b", "c", {1, 2}, {3, 4}, {5, 6, 7}}
};
では?
845 :
814 :2010/03/14(日) 00:24:12
>>844 メンバ変数のうち、Id、Name、Hp_max、Attack、Speedは親クラスから継承しているメンバなのです。
親クラスが存在するクラスではそういう書き方はできなかったかと・・・
846 :
844 :2010/03/14(日) 00:28:37
>>845 初期化用データの格納用に
>>844 の X のような構造体を定義すれば
初期化データをすっきり記述できるんじゃないかってこと
データ部分は関係ないだろ
>>827 どれくらい見られたくないのかにもよるけど、別ファイルにしてスクランブルかけた方が見られにくいよ
>>841 ひでぇ。最初っからそう聞けよ。 >814 みたいにしたせいで無駄なレスがあんなに。
コンストラクタを一つ増やせってことじゃない?
>>845 CTest::CTest(const X &init) : m_id(init.id), ・・・
{
}
852 :
814 :2010/03/14(日) 00:38:12
>>849 すみません。私の聞き方が悪かったせいで、これ以上続けても私が質問したいことを上手く書けるか分かりませんので、
これで終わりにさせてください。
乱暴なようで申し訳ないのですが、以後レスは致しません。
warota
854 :
デフォルトの名無しさん :2010/03/14(日) 00:39:42
┌─┐ |も.| |う | │来│ │ね│ │え .| │よ .| バカ ゴルァ │ !!.│ └─┤ プンプン ヽ(`Д´)ノ ヽ(`Д´)ノ (`Д´)ノ ( `Д) | ̄ ̄ ̄|─| ̄ ̄ ̄|─| ̄ ̄ ̄|─□( ヽ┐U 〜 〜  ̄◎ ̄ . ̄◎ ̄  ̄◎ ̄ ◎−>┘◎
gccのC99拡張機能を有り難がって使ってんじゃねーぞ 聞く方が混乱するだけだ
えっ
template <int num_of_args> class hoge { void operator () (int a1, int a2, ...); }; num_of_argsに対応してoperator ()の引数の数を変動させたいのですが、特殊化をジェネレートするほかにいい方法は無いですかね?
>>857 「ジェネレート」がコンパイル以外のプロセスを指しているのなら、 Boost.Preprocessor が
いくらかマシな手段となるかもしれない。
>>857 これじゃダメっすか
template<int N> class hoge {
void operator()(int a) { BOOST_STATIC_ASSERT(N == 1); }
void operator()(int a, int b) { BOOST_STATIC_ASSERT(N == 2); }
void operator()(int a, int b, int c) { BOOST_STATIC_ASSERT(N == 3); }
};
きりんさんになっちゃいそうです><
>>857 num_of_argsが要らなくない?無いほうがすっきりしないか?
俺もそう思う。 どうせ特殊化で生成するなら、オーバーロードでいいんじゃね?
>>858 boostはよく知らないんですが後でちょっと探ってきます
>>589 これは面白いですね
コード生成は避けられんませんが、ちょっとシンプルになりました
>>860 待ちきれません
>>862 ,863
array<3> a(10, 15, 20);
a(1, 5, 3) = 100;
こんな感じで使おうと思ってるんで、num_of_argsは欲しいです
俺も要らないと思うわ
なぜ[a,b,c]という演算子がないのかっていう有意義な疑問に帰着するわけね。
>>866 x[Index(a, b, c)] で代用できるから
1次元の配列が作れる。n次元の配列に[a]演算子を適用するとn+1次元の配列が作れるならば、数学的帰納法で無限の次元の配列が作れることが証明できる。 早い話がvector<vector<vector<int>>>だね。
ここ数日の質問って何をしたいのか見えてこないのが多いな
c++の文法書ってありますか? 書店に行ってもプログラミングの入門書ばかりで 言語仕様の解説書が見つからなくて困ってる 組み込みやる事になってgcc、GNUARM使う事になったんだが 文法がまるで分からん(K&R〜ANSIの頃のCは随分使ったんだが)
仕様書読めばいいじゃない
>>871 JIS規格ならJISのサイトや取り扱ってる書店で発注すれば購入できたり無料で見たりできるお!!!!!!
文法がまるでわからないのなら むしろ入門書のほうがいいんじゃないのかw ってか組み込みならそんなに難しい文法の知識いらないし、 むしろ環境構築の方が面倒な気がするけどね
>>871 単にCの延長でいいなら入門書読めば事足りるはず。
C++らしいコードが書きたいなら
Effective C++とかMore Effective C++でも読んどけば?という感じ。
厳密な文法が知りたければISO/IEC 14882:2003が言語仕様書ということになってるが、
これを読んで特定の目的を達成するコードが書けるとは思えんなあ。
まぁ気持ちは分かる 入門書だとオペレーターオーバーロードとかnamespaceとかそんなん吹き飛ばして いきなりstd::coutとか使い出すし
>>877 しかも、その場合、ADLまで絡んでくるしな。
組み込みなら組み込みのスレで尋ねた方がいいと思うぜ C++の一般論が必ずしも当てはまるとは限らんから
>>871 組み込みなら C 使えよ。
お前みたいなのが C++ 使うとバグが増える。
とりあえずヘッダ自動生成とかのツール類で
勉強してからにしろ。
デストラクタもないCにいわれてもな
>>881 > とりあえずヘッダ自動生成とかのツール類で
> 勉強してからにしろ。
何を言っているんだw
というか、強い静的型付けもないCなんかで書いたら、誰でもバグが増えるわ。
>>882-884 組み込みは製品になるとスタックダンプとレジスタぐらいしか
なくてアセンブラだけで解析すんの大変なんだぜ。
お前らみたいな糞コードのバグ解析がこっちに
回ってきて迷惑なんだよ。
そういうクソを調教するためにMISRA-Cとかがあります
>>885 組み込みつったって規模があるだろう
それこそメモリが数kbしかないものもあれば、OSが載っているようなシステムだってある
少し極論じゃないのか
Cでバグが減る根拠を挙げてもらおうか
誰もそんな事言ってないから
890 :
デフォルトの名無しさん :2010/03/14(日) 18:41:27
template<typename T> void foo(const T& arg){ if(T::hoge_flag){ func_true(arg); } else{ func_false(arg); } return; } この様なコードがありまして、T::hoge_flagは T型によりコンパイル時に決定されるconst bool型の定数とします。 すなわち T::hoge_flag の真偽によって func_true(arg);とfunc_false(arg);の一方だけが必ず実行され 他方は必ず実行されないことになります。 こういった場合は、テンプレートメタプログラミングを使って 一方だけのコードが実行バイナリファイルに含まれるようにすべきなのでしょうか。 それともコンパイラの最適化を期待して上記のコードのままでも良いのでしょうか。 よろしくお願い申し上げます。
コンパイラの機嫌しだい
>>890 最適化に期待すれば十分だと思うよ。
実測してその部分がパフォーマンスに影響することが分かってから改良しても遅くないよ。
そういう場合テンプレートメタプログラミングを理解できないコンパイラだったら 困る・・・か?そんなバカコンパイラは想定しない方が良いか。
struct when_true{ inline static void func(arg_t); }; struct when_false { (ry }; if_<flag, when_true, when_false>::type::func(arg); 確実性を考えると↑のように関数化しないといけない 結局のところオーバーヘッドは避けられないからif elseのままでいいよ
たとえば、 template<bool N> void func(); でN値による特殊化なんかできるのかな
こんなので切り替えれられるとおも浮けど、わざわざ属性を示すクラスが下からあればいいけど、わざわざ作るなら、ifのほうが分りやすいかもな。 class TypeA{}; class TypeB{}; class hoge :public TypeA { }; class fuga :public TypeB { }; template<class T> void func(const T& obj,typename boost::enable_if<boost::is_convertible<T*,TypeA*>>:type* =0) { } template<class T> void func(const T& obj,typename boost::enable_if<boost::is_convertible<T*,TypeB*>>:type* =0) { } void test() { hoge h; fuga f; func(h); func(f); }
if文の削除なんてあまりにも可読性が低くなってる場合しかオレはやらないな
速度やコードサイズの最適化なんてたかがしれてるだろ
>>896 わざわざややこしくしてないか?
それだったらenable_if_cにして直接T::hoge_flagを突っ込めばいいんじゃん
typename boost::enable_if_c<T::hoge_flag>:typeと
typename boost::disable_if_c<T::hoge_flag>:typeだけで
他にクラスや関数を用意する必要はないはず
まあこんなことしなきゃならないほどカツカツなら
他に検討すべき箇所があるんじゃないのかね
>>895 できるっしょ。
template<bool b>
void func(){〜};
template<>
void func<true>(〜);
これでおkでは?
もう面倒だからboolじゃなくて関数ポインタででも持たせとけよ。
関数ポインタは最適化の障害で(ry
コストとコードサイズ小さくしたいのにカンポはねーよ・・・
結局ifelse書いて最適化に期待するのに落ち着きそうだな 関数化するまでも無い分岐の場合は特にそうだろう
この状況で関数ポインタ持たせたら 逆効果じゃねぇかwwwww
コンパイル時に定まるif elseで絶対に実行されないことが 分かる場合、それでも最適化できないバカコンパイラって 知っている? それを最適化できないとなるともっと重大な所でも 最適化できなさそうな気がするが。
Conceptさん・・・Conceptさんを呼べ!!
templateの部分特殊化とSFINAE。 メンバT::swapが存在し、かつvoid (T::*)(T &)が&T::swapに置き換え可能ならば (その場合のみ)has_swap_implの部分特殊化が選択される。
カードゲームの効果解説かと思った。
>>888 >>871 は C はそれなりに書けるようだが、
解説書見ながら C++ で書いてより高品質なソフトが
書ける理由がないだろ。
どうせ new[] したのを delete するようなコード
書いて地雷仕込むのがオチ。
>>905 まず、has_swap<T>はどんな型にも適合するのでhas_swap<hoge>の実体化が行われる。
コンパイラはhas_swap<hoge>の基底クラスとして、has_swap_impl<hoge, void>を実体化しようとする。
なお、has_swap_implの第2テンプレート引数は省略されているのでデフォルトのvoidが使われる。
has_swap_impl<hoge, void>を実体化しようとした際に、
コンパイラはまず、より特殊化されたバージョンである
14行目のバージョンに適合するかのチェックを行う。
ここで問題は、typename has_swap_helper<T, &T::swap>::type が void と一致するかどうか。
・メンバ関数としてvoid T::swap(T&)が存在するならば、has_swap_helperのテンプレート引数が確定し、
かつ4行目のテンプレートに適合するので、4行目のテンプレートが実体化され、voidになる。
すると、has_swap_impl<hoge, void>は14行目のバージョンに適合する。
・void T::swap(T&)が存在しないならば、適合するhas_swap_helperは「存在しない」。
通常の感覚ならばエラーになりそうだが、 SFINAEの規則によってエラーとはならず、
単に14行目のバージョンが候補から除外される。
コンパイラは次に9行目のバージョンの実体化を行おうとする。
9行目は何でも適合するので、has_swap_impl<fuga, void>は9行目のバージョンに適合する。
あくまでもhas_swap_impl<hoge, void>がどれにマッチするかが問題なので、
たとえば6行目のtypedefをintに変えたりするとダメ
(その場合、9行目を class U = int にすればいい)
っていうオーバーロード解決に至るまでの経過を出力してくれるコンパイラないかなぁ 特殊化とかADLとか絡んでついていけない時がままある
言い出しっぺの法則発動
あ、
>>910 間違えてた。
誤) ・void T::swap(T&)が存在しないならば、適合するhas_swap_helperは「存在しない」。
正) ・void T::swap(T&)が存在しないならば、has_swap_helperのテンプレート引数が確定しない。
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct TestData { int id; char *name; char *sp; char *sx; int nr_param; char *param; } TestData; #define PARA(max,at,sp) ":" #max "," #at "," #sp static TestData test_array[] = { { 1, "NA", "SpA", "M", 3, PARA(0, 0, 1) PARA(2, 3, 4) PARA(5, 6, 7), }, { 2, "NB", "SpB", "???", 1, PARA(1, 2, 3), }, }; void dump_testdata(TestData *t) { int i; const char *p; printf(" Id:%d, Name:%s, Sp:%s, Sx:%s\n", t->id, t->name, t->sp, t->sx); p = t->param; for ( i = 0; i < t->nr_param ;i++) { int m, a, s; m = atoi(p = strchr(p, ':')+1); a = atoi(p = strchr(p, ',')+1); s = atoi(p = strchr(p, ',')+1); printf(" param: max:%d, attack:%d, speed:%d\n", m, a, s); } } int main(void) { dump_testdata(&test_array[0]); dump_testdata(&test_array[1]); return 0; }
>>907 ,910
どうもありがとう、なんとなくわかってきた
なるべく特殊化が強いのを優先的にリストアップして最初に合致したやつを使うということですね
C++使ってちょうど2年半の者です。
テンプレートメタプログラミングって
とても難解そうで ほとんど学んでいないのですが、
例えば
>>890 さんの場合ですとどうすればいいことになるのでしょうか。
どなたかコードを(boost::mplのような出来合いのライブラリを
使用せずに)書いてくださいませんでしょうか。
よろしくお願いします。
>>917 最近、C++を勉強し始めたからテンプレートを勉強していないんだけど
こんな難しそうなのを「みんな出きるのか〜」とビビってたぜ
あぁ〜安心した
メタプロはライブラリ作者のためのものと言い切っても過言ではない 知ってても使う場面は実はそれほど多くない(なくても実装できることが多い)し 使える場面だとしてもすでにできの良いライブラリがあるからそっちを使うことになる
これは静的(コンパイル時)なのか動的(実行時)なのか とかを意識すると多少理解が楽になる
>>917 boost::mplを使えるようになれば自然と覚えられるよ。
こういうこと言うと否定されるのかもしれないけど TMPって出来合いのライブラリを使うプログラミングだと思う 自分でメタ関数やシーケンスをフル実装してる奴とかいるのかね そういやTMPの本が出版されたんだっけ?
templateでメタプログラミングするのが嫌なら別の方法でメタプログラミングすればいいよ。 template使ってる人は型レベルとの相性が良い(というか型レベルそのものだ)から好きで使ってるだけ。
>>917 これでいいっしょ。
template<typename T, bool b>
void foo_impl(const T &arg) { func_true(arg); }
template<typename T>
void foo_impl<T, false>(const T &arg) { func_false(arg); }
template<typename T>
void foo(const T& arg) { foo_impl<T, T::hoge_flag>(arg); }
まあTMPなんて必要性が感じられなければ無理に使うような物でもないと思うよ。
付け焼刃の知識では早々使えるコードが出てくることもない。
何に使えるのかわかってからでも使い始めるのは遅くない。
まずは既存のコードでどう使われているのか観察することだな。
926 :
917 :2010/03/15(月) 10:53:59
みなさんありがとうございます。 C++0xではテンプレートメタプログラミングをサポートするためだけにあるような 機能が増えると伺っておりましたので、そろそろ勉強し始めるときが 来たような気がしています。
>>922 そうだとおもう。テンプレートは作るのは地獄だけど、使うのは楽になるように作るように心がけてる。
関数テンプレートなんか型推論で殆ど型引数を書かなくてすむのに正しいコードが出るんだから、丁寧に作った関数テンプレートは使う側にとって大きなメリットがあると思う。
>>927 お前はテンプレートメタプログラミングってなんだか理解しているのか?
> 関数テンプレートなんか型推論で殆ど型引数を書かなくてすむのに
> 正しいコードが出るんだから、丁寧に作った関数テンプレートは
> 使う側にとって大きなメリットがあると思う。
>>922 もみんなもテンプレートメタプログラミングの話をしているんだけど。。。
929 :
928 :2010/03/15(月) 13:18:35
ああ、分かった。
>>927 はTMPがTeMPlateの略だと思ってた訳か。
これで文脈が繋がった。
環境依存OKなスレで聞きなよ
932 :
930 :2010/03/15(月) 17:21:02
>>931 もしかして自分だけですかね?Temporary Internet Filesの特性かと思っていました。
それで?C++という言語の何を訊きたいの?
return static_cast<931::環境依存>(930の悩み); //invalid static_cast form type "932.オレだけ?" to type "世界平和"
935 :
930 :2010/03/15(月) 17:52:06
C++で作って詰まって短絡的に聞いてしまいました、すみません。 D:\Temporary Internet Files\Content.IE5を見たところindex.datがあるので、ここでファイルとアドレスを関連付けて \Temporary Internet Filesに表示させてる? datをC++で読み込んで目当てのファイルを見つけることは可能でしょうか?
_,,_ /´o ヽ ,.ィゝ l  ̄ヽ l l ヽ___ / ,,...---`ニニニ==、,,__ l / ヽ ヽ ヽ ヽ ヽ ヽ ヽ l三三三> | iヽ ヽ ヽ ヽ ヽ ヽ ヽ/三三/''ー- 、 ヽ. ヽ、ヽ ヽ ヽ ヽ ヽ.∠三=‐''´>‐--‐' ヽ、`'''ー‐---‐'''´_,,...--‐'''´ `''ーッ--t_,r'''´ _/._/
>>935 そうでなくて、Windowsという環境依存なプログラムについては「環境依存OKなスレで聞きなよ」ってことでしょ
939 :
930 :2010/03/15(月) 19:00:08
スレチですね。見当違いですみません…
>>925 二つ目のfoo_impl()はコンパイルエラー起こすだろ
関数テンプレートで部分的特殊化は無理
勘だけど 43、44行目あたりかな
見た感じだと44行目か36行目のどっちかだな
見てないけど44行目かな
どうみても44が--
>>871 です
>>876 ありがとうございます、一番参考になりました
近日中に都会に出かけるのでwあったら立ち読み&購入検討してきます
何度かパーサを書く仕事をしたので、どうしてもライブラリより構文に目が行ってしまいます
最近はそういうの流行らないみたいですね
もはやIBM流の構文チャート?やBNFで定義できるような言語じゃないとは
噂で聞いてはおりますが…
>>941 添え字10のアクセス違反って出てるじゃん
m_array[9]に値入れた後にjをインクリメントしてるんだろ
>>947 は組み込み自体やった事なさそうな感じ
class hoge { const fuga &f; public: hoge() : f(fuga_sub()) { } }; const参照はテンポラリオブジェクトを束縛すると聞いたんですが、↑のようにするとバグります。なぜなんでしょうか?
fはhogeのコンストラクタスコープでしか生きてないインスタンスをさしてるから
>>948 ええ、組み込みは初めてです
使ってもいいライブラリはサンプル等あるんで問題ないんですが
コンストラクタの初期化リストなんて初めて見ました
トッパンのC++の本なら昔買いましたが、今更役に立ちませんよねw
>>949 初期化リストで使った場合、コンストラクタの終わりまでしか延命されない。
規格の 12.2 p5 より。
> ... A temporary bound to a reference member in a constructor's ctor-initializer
> persists until the constructor exits. ...
その特別ルールが役に立つのはほぼ自動変数だけ。
>>950 ,952
仕様でしたか・・・
静的に安全にポリモれると思ったんですが、残念です
コンストラクタでは初期化と代入を区別したがるのになんで それ以外の初期化ではint a(0);じゃなくてint a = 0;を使うのですか?
コンストラクタは初期化しかしないよ。 int a = 0;も初期化であって、代入ではないです。
>>953 scoped_ptrやshared_ptrで掴んでおけばOK
>>955 説明不足でした。例えば、
class A {
int a
public:
A(int _a);
};
というクラスがあったとして、コンストラクタに
A::A(int _a) { a = _a; }
よりも、初期化子リストを使った
A::A(int _a) : a(_a) { }
のほうが良いと言われているのにどうして組み込み型の場合は
int a(0);
じゃなくて
int a = 0;
と書くのかという意味です。
>>957 組み込み型だからという問題ではない。
:{a=_a;}は代入。しかもデフォルトコンストラクタで初期化してさらに代入するという無駄がある。
:a(a)もint a=0;も一発初期化で無駄が無い。
そこらへんおモドカシさを解消するための複合リテラルであり右辺値参照なんだな
>>957 int a(0);もint a=0;も機能は同じ。
だけど、組み込み方とクラスで同じように式の形式で書けたら便利な場合がある。たとえば、
int a=b+c*d;
std::complex<double> ca=cb+cc*cd;
??957 ひょっとして int main() { int a(10); } と書かずに int main() { int a = 10; } と書くのはなぜかって話かな?
それは単なる慣習以上の物ではないな。
C言語じゃ int a(10); って出来ないからね
957はC++0xで幸せになれそうだな class A { int a = 0; }; これが出来るようになるから
class A { int a(0); }; はまだかね
>>964 メンバの初期化をそうやって書けるようになるってこと?
そのメンバはintの様な組み込み型以外でもおkだったりする?
gccは既にdoubleも初期化できるようになってるな
rubyがコンストラクタをthis()って書けるらしいうらやましい するとデストラクタどうなるんだろう
siht
shitかと思ったじゃないか。 あながち間違ってない気がするが
コンストラクタやデストラクタの名前は なんでわざわざクラス名と同じになってるんだっけ。 constructor() destructor() じゃダメな理由をどこかで見たんだが 思い出せないでござる
どっちも4文字だと綺麗になりそうだな
rubyはinitializaでデストラクタなし D言語がthisと~this だった記憶が
>>971 親クラスのコンストラクタとか呼び出す時のためとか?
975 :
957 :2010/03/16(火) 23:17:38
皆さんレスありがとうございます。 int a = 0; も int a(0); も初期化なのですね。安心しました。
977 :
974 :2010/03/16(火) 23:25:13
>>976 ところがC++には多重継承という変態物があってだな…
codepadはboostと0xにさっさと対応しろ!
Hoge h(); は関数の宣言
boostは使えるけど古い
>>971 必ず存在するかじゃないか?
予約名を増やしたくないとか?
C互換をできるだけ保つために、予約語を増やしたくなかったんじゃない そもそも、予約語を増やしたくないってのが C の基本の考えじゃなかったっけ static が静的メンバだったりファイルスコープだったりと、同じ語でも複数の意味を持つことがある
struct A{ operator this() {} // ctor operator ~this() {} // dtor }; これはきもいか・・・
>>979 codepadはboostに対応しているだろ?
>>983 過去にがんじがらめになっている、
そんなC++が大好きです。
C++0xをブラッシュアップして新しい言語作るべき
990 :
デフォルトの名無しさん :2010/03/17(水) 15:06:12
991 :
デフォルトの名無しさん :2010/03/17(水) 15:07:38
有るコンテナから要素をランダムに複数個選び、それらの要素を取り出してコンテナから削除する という動作を繰り返す場合stlでいうとどのコンテナが最適でしょうか?
list
たまにはD言語のことも思い出してあげてください
むしろ同一人物だったりして
通勤中、やさしいC++片手に、読む度にどたまが良い具合に火を噴いてる所だけど、 最近すこしずつスレに書いて有ることが見えてきたよ…内容はまだあんまし判らんけどね 給料日が来たら、今度はEFFECTIVE C++を買ってくるんだ…
何でもそうだけどメモに自分の解釈を図に示したりして読んだ方がわかりやすいよね。 というか通勤中に読書ってどういうこと?車運転しながら本読んでるの?
>>997 いや、通勤で読書と言えば電車とかバスだってばさw
しかし仕事帰りに読むと、良い具合に睡眠導入作用がががg
死ね
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。