これは乙じゃなくてなんとかかんとか
9 :
デフォルトの名無しさん :2009/09/01(火) 17:02:07
torakan2.exe の 0x004012f3 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x01bb9000 に書き込み中にアクセス違反が発生しました。 上記のようなエラーが発生してしまいました。 どうか、ご指導・ご鞭撻のほどよろしくお願いします。
10 :
9です :2009/09/01(火) 17:04:16
プログラムを貼りつけたいのですが、 貼りつけられるサイトをどなたかご存知でしょうか?
12 :
9 :2009/09/01(火) 17:33:59
>>12 j+k>=8927 にしてみたらどうなる?
delete [] L はないだろ。
ファイルのオープンに失敗したら、exitするなりreturnするなりしろよ。
ファイルのクローズに失敗したら、どうすればいいのでしょうか。 デストラクタでクローズしています。
クローズは、バッファに残ってるまだ書き込まれてないデータのフラッシュも行う クローズに失敗したということは、書き込まれなかったデータがいくらかあるかもしれないということだ 書き込みが失敗したという事実をユーザに通知するべき
デストラクタでクローズしてるのでそれは出来ません。
ユーザーアンフレンドリーなプログラムだな・・・ 自分専用なら別にいいかもしれないが (何かあっても自業自得なだけだし)
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
23 :
20 :2009/09/01(火) 19:57:26
ビープ音でモールス信号を発生させ、エラーの内容をユーザーに通知することにしました。
失敗したときの対処を行いたければ、デストラクタに頼ってはいけない。 ファイルを閉じる処理とそれに失敗したときの処理を明示的に行う。
class test { virtual ~test() = 0 {} }; この文法って相変わらずVC++専用?
うn
すまんpublic付け忘れた
>>25 これって何?
仕事のない純粋仮想デストラクタ?
全順序 "total order" とは、任意の値の集まりを一列に並べたとき、その 結果がただ一通りだけになるような順序関係のこと。 この場合、等値関係 "equality" と等価関係 "equivalance" はまったく同じ 関係となり、等価な要素同士を入れ替えても並べた結果としては同じになる。 たとえば、整数の大小関係は全順序である。 弱順序 "weak order" とは、全順序よりも要件を少し弱くした順序関係で、 等値でない2つの値を等価とみなすような順序関係を含めたもの。 この場合、並べ替えの結果の中で等価な値同士を入れ替えることで、異なる 並べ替えの結果が得られることがある。 たとえば、整数の大小関係は弱順序でもあり全順序でもあるが、整数の 下一桁を無視した大小関係は弱順序であって全順序ではない。 厳密弱順序関数 "strict weak ordering" とは、弱順序を定義する関数で、 関数 r と任意の値 x, y, z についての以下の要件を満たすもの。 - r(x, x) が常に false となること。 これは非反射性 "irreflexivity" といわれる性質である。 - r(x, y) && r(y, z) が true なら r(x, z) も true であること。 これは推移性 "transitivity" といわれる性質である。 - r による等価関係 !r(x, y) && !r(y, x) を equiv_r(x, y) として、 equiv_r(x, y) && equiv_r(y, z) が true なら equiv_r(x, z) も true であること。つまり、等価関係にも推移性があること。 r の逆の否定として得られる r'(x, y) = !r(y, x) は明らかに非反射性を 満たさないが、同じ弱順序を定義する関数といえる。 たとえば、整数の大小関係において "<" は厳密弱順序関数である。 このとき "<" の逆の否定である "<=" も同じ順序を定義する関数であるが、 厳密弱順序関数ではない。 呼び名に「厳密」とあるが、これは英語で等号無しの不等式 "<", ">" を "<=", ">=" と区別して "strict inequalities" と呼ぶことから付けられた 記号的なもので、言葉どおりの意味を表すものではない。
31 :
30 :2009/09/03(木) 06:06:42
"strict weak ordering" を人に説明しようとしてググったけど、日本語で わかりやすい記事が出てこなかったんで、むしゃくしゃして C++ プログラマ 向けの(数学用語をなるべく避けた)説明をがんばって1レスにまとめてみた。 間違ってるとか、もっと短くできるとか、もっと簡単にできるとか、添削して もらえると助かる。 特に最後に挙げた "strict" の由来あたり、英語版 Wikipedia をうろうろして ひねり出したものなのでいまいち自信が無い。
どれくらい厳密さを求めているか、背景まで知る必要があるかによるけど、 いかにも数学っぽくてかなりの人が拒否反応を示しそう。 ・比較したいものの対象全体を考えます。 ・同じと見なすものでグループごとに分けます。 ・グループ間で順序付けします。 ・同じグループ内の要素間では false を返し、別グループの要素間では先ほどグループ間で決めた 順序付けに従って、true か false を返します(func(a,b) で a < b なら true, b > a なら false)。 これが strict weak ordering になります。 これで実用上問題ないんじゃない?
あえて抽象度を落として、funcの名前をlessにでもしてしまうとか
34 :
デフォルトの名無しさん :2009/09/03(木) 18:13:45
エクセルのような表計算ソフトを作る場合、テーブルの表示には何を使いますか?
GDI関数
std::stringstreamを使って、デバッグログの出力をしたい std::stringstream debug_out; debug_out << "debug log" << std::endl; ログ結果をIDEのデバッグウインドウに出力したいので 1ライン出力ごとにOutputDebugStr()をコールして内容を出力したい。 ただし、1ライン書くごとにOutputDebugStr()直接埋め込むのは避けたい。 debug_out << "debug log" << std::endl; ::OutputDebugStr( debug_stream.str().c_str()); debug_stream.str(_T("")); // <-これを毎回書くのは避けたい 表面上追加・変更は最小限に、OutputDebugStr()コールを追加することは出来ますか?
OutputDebugStringStreamを作るというのはどうか
>>37 お答えありがとうございます。
それが正攻法だとは私も思ってますが、
std::streamの知識が無いので、出来ればやりたくない。
恒久的に残すつもりはないので、楽ならどんな方法でもかまわない。
何かありませんか?
また、stringstreamはコンストラクタでopenmodeを指定しますが、
もう既にあるインスタンスを再構築したい場合は、どうすればいいんでしょうか?
debug_stream = stringstream(std::ios::out);
これは駄目のようです。
それなら debugendl を作って endl の代わりに使うというのは #define endl debugendl とかやってもいいし
40 :
30 :2009/09/03(木) 20:52:19
>>32-33 ありがとう。
うーん。あれでもだいぶ削ったつもりだったんだけど、確かに挙げてもらったのと
比べるとまだまだ数学っぽさが色濃いね。
で、今回調べたきっかけが、「厳密って何?」「弱ってことは強もあるの?」とか、
「結局 "<" と同じようにすればいいだけなのに、なんでそんな変な名前なの?」とか、
そういうところだったんで、なんとかそこらへんの疑問がひととおり片付くようなものを
書いたつもり。
これはつまり「背景まで知る」のを前提にしてたってことになるね。後出しでごめん。
>38 大分前に書いたコードから抜粋してきたけどこれでそれなりに動かない? #include <iostream> #include <sstream> #include <windows.h> class odstringbuf : public std::stringbuf { protected: virtual int sync(void) { OutputDebugString(str().c_str()); str(""); return 0; } }; int main(void) { odstringbuf odsbuf; std::ostream ods(&odsbuf); ods << "debug log" << std::endl; return 0; }
>>41 それを使ったらうまくいきました。
今後もそれを使っていきます。
ありがとうございました。
>>29 ,43
read() は書式なしの読み込み処理として備えられているものなので、問題ない。
45 :
29 :2009/09/04(金) 12:08:03
readってeofに到達したときに読み込めたバイト数をどうやって検出するの?
>>46 何を言っているのか分からん。
分かるように書き直して
1000バイト未満のファイルをreadで1000バイト読み込もうとしたときに何バイト読み込んでエラーになったか知りたいのです。
>>48 あーなるほど、
if(is)とかでエラーになったことはわかるけど、
具体的に何バイトでエラーになったかはどうやって調べるのか、って意味か。
・・・ごめん分かんない。
有識者plz
gcount()
51 :
デフォルトの名無しさん :2009/09/04(金) 20:07:28
STLコンテナを作りたいんだが、 面倒なのでstd::vectorをpublic継承したい。 メンバ変数がなければ問題ないのかもしれないが、 メンバ変数を持ちたいとき、なにか妙案はない? ・std::vectorをメンバ変数として持つ ・private継承する だと、メンバやtypedefを全部書かなきゃならん。 要はstd::vector&へのキャストを禁止したいんだが。
52 :
51 :2009/09/04(金) 20:28:08
自己解決。 template <class T, class Allocator = std::allocator<T> > class protected_vector : private std::vector<T, Allocator> { public: typedef allocator_type allocator_type; typedef const_iterator const_iterator; typedef const_pointer const_pointer; ... protected: ~protected_vector(); } こういうのを作っておいて継承するわ。
typedefがおかしいぞw
55 :
デフォルトの名無しさん :2009/09/04(金) 20:46:24
streamへ出力するとき、 行の先頭位置を設定するマニプレータはありますか? cout << tab(4) << "aaa" << endl << "bbb" << endl; ↓ ____aaa ____bbb 例えばこうすると、常に4文字分スペースが入って出力されるようになるような。
56 :
51 :2009/09/04(金) 21:09:14
>>53 これでいいんでね?
privateなものをpublicで公開する的な意味で。
>>52 typedef してるところは using でいいんじゃね?
std::vector<... > とか書くのが嫌なのかもしれないけど、いっこ base_type を typedef すれば
よさそう。
58 :
51 :2009/09/04(金) 21:33:46
面倒だからprivate継承、とかはろくなもんじゃないけどな…
60 :
デフォルトの名無しさん :2009/09/04(金) 23:56:09
_beginthreadexでスレッドを呼び出す場合スレッド側で_endthreadex(0);と書くのは必要でしょうか? 単にreturn 0;と書いているサンプルもあるので
62 :
61 :2009/09/05(土) 00:02:40
63 :
デフォルトの名無しさん :2009/09/05(土) 00:38:35
C++0xのconstexprと同じ動作を 既存のVC++でやるにはどうすればいいのですか?
>>64 VC++でC++0xコンパイラを開発する
どうせコンパイル時定数になるんだから PHPか何か埋め込んで計算させるのはどうだ
>>67 釣り?
comparatorの仕様をちゃんと調べればすぐに判ることだが、
qsort()の比較関数とは違うぞ。
69 :
67 :2009/09/05(土) 04:59:43
>>68 了解しました。単に true/false を返すだけでよかったんですね。
70 :
デフォルトの名無しさん :2009/09/05(土) 12:55:43
std::vector<double>::iterator() == std::vector<double>::iterator() こういうことはできない? VC++だとassertっぽいので落ちるんだが。 イテレータの代わりにポインタで書かれたプログラムを書き直していて躓いた。
何でイテレータを空引数のコンストラクタで生成してるんだ?
hogel() = default; これを普通のC++で書くとどうなるの?
>>70 これは何したいコード?
意味論的に狂ってないか?
>>74 C++0xのコードを普通のC++に書き直したいの
>>72 // hogel() = default;
hogelクラスのデフォルトコンストラクタの話でしょ? 諦めて書きましょう。
>>76 で何が不満なの?
普通のC++で明示的に書けないからC++0xで追加されたんじゃないか。
>>71 ,73
ポインタをイテレータで置き換えてるんで、
NULLポインタを表すものがほしかった。
>>80 それは何か方針が間違っているよーな。。。
詳しくは次の方どーぞ
>>80 コンテナの end() が、だいたいその役割。
>>77 暗黙のデフォルトコンストラクターとかコピーコンストラクターとかコピー演算子とかが副作用バリバリで余計なお世話だと、昔は思っていた。
でも今は、メンバーにPOD型を止めてshared_ptrとか他のオブジェクトとか使うことでRAII前提にしたら、暗黙の系との親和性が良くなってすごく便利に感じるようになった。例外安全にもなるし一石二鳥ということで
古いC++の本見てたらoverloadなんて予約語を見つけた 廃止されたらしいけど、こんなのあったなんて知らなかったよママン
constexprってなんなのですか? 普通のC++でコンパイルとおらねーぞ 助けてください
>>85 今度の規格改定で入る予定のキーワード。constがもっと強くなったようなもの。
普通のプログラムならまだ使っていないと思うんだけど。
templateを使って、ある型Hogeが来たら対応する型Fugaを返すといったような型のマッピングが したいんですが、複雑で柔軟なマッピングがしたいです。 //型のマッピングをしてくれる構造体。Tを与えるとtypeにマッピングされた型が定義される template<typename T> struct type_map{ typedef なにか type; }; という構造体があったとして、「なにか」の部分をうまいことして単純な1対1対応のマッピングだったり 「あるクラスの派生型ならこの型」というような継承関係を利用した多対1のマッピングだったり マッピングの定義箇所がソース上で何箇所かに分かれていたり(例えば、返したい型の定義されているヘッダ) こういうことをしたいんですが、何か方法はありますか? C+
>>87 >単純な1対1対応のマッピングだったり
テンプレートの特殊化でできるよ
>「あるクラスの派生型ならこの型」というような継承関係を利用した多対1のマッピングだったり
boostのis_系メタ関数使って特殊化
>マッピングの定義箇所がソース上で何箇所かに分かれていたり(例えば、返したい型の定義されているヘッダ)
たぶんムリ
>>87 テンプレートメタプログラミングのboostのmplを使えば型のリストを作ることができる。
typedef boost::mpl::list<hoge,huga,piyo> katalist;
これにboost::mpl::foreachとかでいろいろ処理を記述できる。
boost::mpl::mapを使えばマッピングが簡単になるかもしれない。mpl::mapは使ったことないんで自信ない。
こういう時どうすればいいのか教えてください HANDLE h = open(...); OBJ *o = new OBJ(h); return o; 上記の用に、OBJのコンストラクタに ハンドルを渡す必要があるのだけど エラー処理を追加すると、メモリ確保に失敗した場合 オープンして、すぐクローズする羽目になる。 HANDLE h = open(...); try { OBJ *o = new OBJ(h); } catch (std::bad_alloc& e) { close(h); throw error; } 処理の流れ的には、メモリ確保に成功したらオープンして〜 というほうが自然なのだけど、ハンドルを受け取る コンストラクタしかないので出来ない。 さらにopen()やclose()も失敗する可能性があるので その処理も追加すると、煩雑になってしまう。 なにかいい方法ありませんか?
HANDLEとOBJを修正出来ないならそうするしかないだろうよ
ソースの煩雑さが問題なだけなら、auto_ptrのようなHANDLEを自動解放するクラスを作ってデストラクタにやらせる どうしてもメモリを先に確保したい?別にいいんじゃないの?
placement newでメモリ確保
>>90 HANDLEを管理するオブジェクトを作って包含させる。
するとOBJのコンストラクタが例外を送るとOBJに包含されているオブジェクトのデストラクタが自動的に呼ばれ、自動的にhandleがクローズされる。そのためtry-catchが不要になる。
ただしこの例はcloseでは例外を送出しないと仮定している。
#include <boost/shared_ptr.h>
using boost::shared_ptr;
class Handle
{
HANDLE handle;
private:
Handle(const Handle&);//no copyable
public:
Handle(Handle hand):handle(hand){};
virtual ~Handle(){close(hand);}
};
class Obj
{
shared_ptr<HANDLE> ha;
public:
Obj(const shared_ptr<HANDLE>& hand):ha(hand){};
};
shared_ptr<Handle> h(new Handle(open(...));
Obj*o = new OBJ(h);
>>94 なんか違ってたスマン
#include <boost/shared_ptr.h>
using boost::shared_ptr;
class Handle
{
HANDLE handle;
private:
Handle(const Handle&);//no copyable
public:
Handle(HANDLE hand):handle(hand){};
virtual ~Handle(){close(hand);}
};
class Obj
{
shared_ptr<Handle> ha;
public:
Obj(const shared_ptr<Handle>& hand):ha(hand){};
};
shared_ptr<Handle> h(new Handle(open(...));
Obj*o = new OBJ(h);
え?先にOBJのメモリ確保してからHANDLEをオープンしたいって話しじゃないの?
煩雑にならない方法を聞いてるようにしか…
>>88 ,89
ありがとうございました。
やはり、それなりにはできそうですね。でもあまり柔軟性は高くないようで・・・
この辺C++0xとかで改善されるといいですね〜
boost::mplのレベルの柔軟性でも不満ならC++0xにもそれほどは期待できないと思う
C++0xの言語レベルでのテンプレート関係の強化って コンセプト亡き今は可変長引数のサポートくらいしかないからなぁ あとはboostよりずっと貧弱な標準ライブラリがあるくらいで
template 混じりの typedef がヤバい程便利で且つ混迷を深める凶悪兵器だと思うがね
>>101 C#でtypedefのないジェネリックスを使うと、mplでのtypedefのやばいほどの便利さをひしひしと感じる。何で無いの?
なんでと思ったなら言語使用の上っ面だけでも見なおせよバカ
>>100 いや、BoostがC++0xに準拠したらもうとんでもないライブラリが
できるだろう。期待しちゃうぞ。
>>104 boostのtypeofエミュレーションがC++0xでネイティブサポートされてるだけでも大きな効果があるぞ。
でも0xはで無い 2015年まで出ないぞ
C++0fってことか?
auto decltype rvalue lambdaあたりは実装してるコンパイラもちらほら出てるし。 boostがその辺のコンパイラのサポート状況の違いを吸収してくれると嬉しいんだが。
tainting checkみたいなのをランタイムコスト無しでうまく実装できないかなぁ、 constが感染するような感じの挙動で
template<typename T> T *NewInstance() { void *p = AllocMemory( sizeof(T) ); return new(p) T; } これの配列版を作りたいんですが、どういう実装になるんでしょうか。
何のためにそんな関数を作ってるのかが分からない
>>111 十分なサイズの領域を確保して、ループをまわす。
ちなみに、その実装だと T のコンストラクタで例外が発生したときに p が漏れるよ。
>108 >auto decltype rvalue lambda このあたりは既に吸収しはじめてると思う。 少なくとも BOOST_NO_XXXX マクロは全て存在する。 >111 std::uninitialized_fill() とか使えばいいんじゃね?
auto, decltype: Boost.Typeof rvalue reference: Boost.Move lambda: Boost.Lambda ってとこか。Moveはまだacceptされてないけど。
vectorは、resize(N,0)で初期化できるものと信じていたが 生成時以外だと無理なのね。 既に使用済みのvectorを0クリアしようとこれ使っていたら、消えてない。 初期化はどうやったら良いんですか?
117 :
116 :2009/09/07(月) 03:08:07
あげ
>>116 vector<type>().swap(v);
>>116 Effective STL読んだ方がいい
v.clear(); v.resize(N, 0);
サンクス
>>119 読んでないけど既にある領域を壊さないを壊さない仕組みなんだろうけど。
>>118 Effective STLではそう書いてあるけど
v.swap( vector< type >() );
じゃなんでいけないんだろう。
こっちのほうがわかりやすいと思うんだけど^^;
>>122 vector::swap()の引数は非constなわけで(スワップするんだから当然)、
そこに一時オブジェクトを渡しちゃダメでしょ。
いや、すまん勘違い。 一時オブジェクトとconst云々は元のやり方にも言えることか。
いやあってる。 一時オブジェクトは非const参照引数には渡せない。 一時オブジェクトのメンバ関数を呼ぶのは問題ない。
0クリアってstd::fillを使えって話じゃないの?
いや、vector::assignじゃないの普通 または v = vector( n, 0 ); ここでswapを出してくる感覚が理解できん
まぁ
>>116 の日本語も下手なんだが、swapが出てくる理由の分かってない奴は
「capacityを0にしたいらしい」という意図を汲み取れ
>>128 最初に resize(N, 0) って書いてあるんだから、ただの誤読じゃねーか。
最初に書いてあるのは「resize(N,0)じゃ駄目でした」だろ
resize(N, 0) で capacity を 0 にしたいわけがない。
「capacityを0にしたいのにresize(N,0)じゃできないんだけどどうしたらいいんですか」 だろ?
んー。代入(operator=、assign)はO(N)の保障だけど vectorのswapはO(1)が保障されているから swapしたほうが速いかも。 vector< int >( n, 0 ).swap( v );
>>127 assignのことすっかり忘れてた
>>128 俺はエスパーになれそうにないな
ところでswapの方が早いとかあり得るのか?
無駄なメモリ確保が入りそうなんだが
>>132 resize(0) なら、そうとも取れるが、 N はどっから出てきたことになるんだ?
>>133 いやいや、その一時オブジェクトの構築に結局O(N)かかるだろ。
>>136 いや、そりゃそうだけど、
>または v = vector( n, 0 );
の右辺の構築も同じくO(N)かかるじゃろが。w
実際、今VCで実験したらswapの方が倍くらい速かった。^^
ちなみに比較したのは、
>>127 と
>>133 ね。
v = vector< int >( n, 0 );
vector< int >( n, 0 ).swap( v );
ちなみに、マッサー本によると
vectorにおいて代入とassignは線形時間、swapは定数時間となってるから
結果どおりでいいんじゃないかと。
vector::assignでいいじゃん。なにか困るの?
assign() を operator = () のただの別名だと思ってるんだろう。
std::fillもついでに計測してくれ
>>141 おぉ、v.assign( n, 0 ) でやったらswapより2%速くなった^^;;;
なお、マッサー本には assign は clear(); insert( begin(), n , u ); と同値と書かれていて(p.329)、
代入と同じではないね。
というわけで、やるならassignかな。代入はコスト的に間違いってことでF/A?
>>142 fill はそもそも resize の要求にこたえてないので実験しません^^あしからず。
assignもcapacity変わらなくね?
>>145 だから、最初から capacity を変えたかった人なんていないんだってば。
147 :
133 :2009/09/07(月) 13:15:14
>>145 もちろん、かわらないよ。
自分は
>>128 じゃないから、
capacityがどうなるかは問題にしてない。
すいません質問があります. VC++のダイアログ形式でプログラムしているのですが 下記のプログラムで myDLG.DoModal() を行うと最初からあったOKボタンを押してもプログラムが死に切っていないようなのですが どのようにすればいいのでしょうか. ググったら無限ループとか永久に待機してるとかっぽかったんですが解決法が良く分かりませんでした. プログラム開始→OKボタン 普通に終了する プログラム開始→ボタン8→ファイル選ぶ→OKボタン ダイアログは消えるがプログラムは完全に死んでないみたい といった状況です. void CtestDlg::OnBnClickedButton8() { // TODO: ここにコントロール通知ハンドラ コードを追加します。 //ファイルダイアログを表示してファイル指定する CFileDialog myDLG(TRUE,NULL,NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "AVIファイル(*.AVI)|*.AVI||"); if(myDLG.DoModal() != IDOK)return; }
>>149 MFC相談室ってスレですかね?
誘導どうもです.
int F() という関数に、__inlineやinlineをつけると、 「関数は値を返すべき」という警告出ます。 つけないと出ないのですが。 これは、予定通りの動作しなかったりしますか?
お前がどんな動作を予定してるのか分からんし
153 :
151 :2009/09/08(火) 03:29:25
具体的なコードはこれですが原因わかりますか。 __inline int kana_chk (unsigned char *p){ if ( p[0]==0xa4 ) if( p[1]==0xf3 || (p[1] >= 0xa1 && p[1] <= 0xf1 ) )return 1; return 0; }
154 :
デフォルトの名無しさん :2009/09/08(火) 03:34:03
これだと、どちらも警告でないのですが・・・ 上のコードだと付けるか付けないかで変わります。 int F() { return 1; } __inline int G() { return 1; }
156 :
デフォルトの名無しさん :2009/09/08(火) 03:36:51
コンパイラのバグと思ってスルーで行こうと思いました。 153とほぼ同じ別の判定関数で、警告でない物もあるので。
サンクス
>>153 コンパイラが正しいな。
字下げを正しくすれば分かる。
__inline int kana_chk (unsigned char *p){ if ( p[0]==0xa4 ) if( p[1]==0xf3 || (p[1] >= 0xa1 && p[1] <= 0xf1 ) ) return 1; return 0; } ?
むしろinlineを付けたままで、 中身を削って確認して欲しい
ヒントない? 値はちゃんと返してると思うけど?
__inline int F (unsigned char *p){ if ( A ) if( B ) return 1; return 0; return 0; } にすると警告でなくなるな。一つ目のreturn 0; はif文の影響うけてるって事? 理由わからん。
if ( A ) if( B ) return 1; return 0; と if ( A ) { if( B ) return 1; } return 0; は別物だったの? しらなかった。 下は警告でない。
まぁ普通に全部ブロックに入れろや ifの構文規則なんかを覚えて頑張ってブロックを省略するより、&&と||の優先順位を 覚える方がまだしも役に立つぞ
inline の有無で警告出る理由は何だ? 教えてくれ
関数の構文が破損してるからだよ。
とりあえず、 警告うんぬんと語るヤツは警告メッセージを貼れ。
169 :
デフォルトの名無しさん :2009/09/08(火) 15:05:09
ある数値計算する処理(クラス)があって、それがとても遅くて高速化したい。 処理の中で、連立一次方程式を解く箇所があって 調べてみたら、同じ式を何度も重複して解いていたことがわかった。 (1例では、4500回中4200回も重複していた) そこで、方程式の解をstlのmapに入れて使いまわすように変えてみた。 結果は次のとおり ○対策無し full time(AVG) = 0.012447 le time(AVG) = 0.005351 rate(AVG) = 0.429899 ○対策あり(map) full time(AVG) = 0.026179 le time(AVG) = 0.003062 rate(AVG) = 0.116979 ※full timeは処理全ての時間 le timeは方程式部分のみの時間 rateは、 le / full AVGは2560回やった平均 le timeは3/5に減ったんでまだいいんですが、 全体としては逆に増えてしまった。 mapの検索、挿入処理を埋め込んだのは方程式部分の中だけで それ以外違いはありません。 遅くなるとすれば方程式部分の時間になると思うのですが、 逆に、それ以外の時間が4倍近く遅くなってしまった。 なんでこうなるかわかりますか?
使うメモリが増えてキャッシュに収まらなくなった、とか?
質問。 基底クラスBを、とあるクラスAに包含した場合 基底クラスBを継承して作ったクラスCは、クラスAで使えるますか? 使えないのならば、どうすればクラスCはクラスAで使えるようになりますか?
ポリモーフィングの話に近いような
mapの中でコピーしまくってるとか? 内部コピーが多発してるようなら、map<T>をmap< shared_ptr<T> >に変えるとか。 検索時間が重いなら、mapをunordered_mapに変えるとか。
>>170 >>173 お答えありがとうございます。
キャッシュミスの可能性ということで、
1つの処理も内部的には区切りがあることに気が付いたので、
区切りに合わせてmapの持ち方を変えて、2種類試してみました。
@は、mapの中にmapを入れる形
full time(AVG) = 0.015926
le time(AVG) = 0.001885
rate(AVG) = 0.118389
Aは、区切りでmapをクリアする形
full time(AVG) = 0.024784
le time(AVG) = 0.016827
rate(AVG) = 0.678919
元より良くはなりこそしませんでしたが、@は大きく改善しました。
どうやらmapが大きくなりすぎてキャッシュミスしていたようです。
一応方程式部分は改善されているので、バランスをとる方向で
考えてみたいと思います。ありがとうございました。
>>173 mapはキーもアイテムも、12~200byteぐらいで、コピーの重さも微妙です。
unordered_mapは知りませんでした。調べてみます。
>>171 クラスAにクラスBのポインタを持つようにすれば、使えるますよ。
mapは、メモリ食う。 googleのmapは消費量少ない。 基本的に、mapはプログラム使う側の負担減らす目的が主と考え vectorなどに入れておき、一致するか確認した方が速い。 ケースにはよるが。
問題を見ないとわからないけど、そこまで何回も同じ式を解くってことは、 根本的に理屈/アルゴリズム見直した方が良さそうな気がする。 それで map なのかも知れないけど、map 持ち出す必要あるのかな。
178 :
505 :2009/09/09(水) 01:41:09
>>176-177 アルゴリズムはよく知られたもので、
それをそのまま使っているので改善は出来そうにありません。
なぜmapなのかですが、元の行列(今回のケースでは最大36x36)から、
一部の行列を抜き出して、連立方程式として解くという形であり
抜き出すパターンの組み合わせ数を考えるとmapになりました。
実際、解を再利用することで、求解処理時間は半分以下に
なっており、効果はありそうなだけに残念なところです。
また、何も手を加えない元の状況を更に調べてみたところ
std::count()でstd::vector< uint >の要素数を求めている箇所が2つあり
それが全体の処理時間の2割を占めていました。
処理時間の割合 「方程式求解 : ↑ : その他 = 4 : 2 : 4 (割)」
当初、求解にかかる時間が殆どで、それ以外はゴミみたいなものだと
考えていただけに、こんなものがこれほど時間を喰うとは以外です。
なにをしたいのか、簡略化したものでも、書き込んだらいい方法でるかも?
36次元から、何次元を抜き出すんだ?
たとえば、double 10*10を解くとしたら、データ、解記録に800バイト程度必要。 4000ほど同じのが現れるという書き込みから、記録に必要な容量は、3Mバイト程度。 このくらいではメモリ不足にはならない。 mapの検索が遅い可能性あるから、解こうとする行列のハッシュを自前で計算してみるとかは? 10*10を一列に並べてCRC32計算して、そのうちの何ビットかをキーにして、データの一致を確かめるとか。
なんで800バイトなんだろ
行列記録に必要なのは、 8バイト * 100 だろ。
なんで36*36*8byteじゃないのかなぁと思って
185 :
184 :2009/09/09(水) 02:36:36
あああ、ごめん。ほんとごめん。
キーのサイズがそれだけあるってことは、二分木探索するmapよりハッシュ探索する unordered_mapの方が適切な気がするけど
>>169 そもそもちゃんと最適化して計測してるんだろうな?
それにしても,ちゃんと profiler かけてるのかな。 ちゃんと時間を取る場所を押さえないで「最適化」するとロクな事無い。 状況証拠から多分あってるんだろうけど、他の場所もある程度 いじるわけだろうし。
確かに最適化無しにコンパイルしてたら笑えないなw しかし、uint(=unsigned intだよな?)が要素になってるvectorへのcount程度で そんなに時間食ってるってのは、最適化されてないんじゃないかと疑いたくもなるな
vectorに対するcountのオーダーはO(N)だから要素多ければそれなりの時間はかかるだろ。 しかし全体の2割ってのはなんだろうとは思うな。
仮令巨大なsizeのvector<uint>であっても、先頭からシーケンシャルにアクセスするcount()は結構速いよ。
using namespace std; ofstream ofs("filepass"); で開いたofsに改行を出力したいのですが、 ofs << cout; だと出力できないのでしょうか? "\n"だとバッファがフラッシュされないとか聞いたものでして coutでやろうと思ったのですが。
193 :
192 :2009/09/09(水) 19:55:12
具体的には #include <iostream> #include <fstream> int main() { using namespace std; ofstream ofs("filepass"); ofs << cout; return 0; } で出力先のファイルに 0x46f0c4 と表示されるだけです。
改行したいだけならstd::flushもある。
197 :
192 :2009/09/09(水) 20:45:23
>>194-196 ありがとうございました。
std::endlで出来ました。
なんか重大な理解不足をしでかしている気がしますので
1から勉強しなおしてきます。
>>197 coutはostream型のオブジェクトだから、君が作ったofsの親戚みたいなもの。
>>193 はいわば、カメラでカメラを撮影したみたいな感じ。
>>198 ありがとうございます。
マニピュレータとやらも勉強してまいります。
iostreamなんか勉強しても何も得しない 素直にprintf使いなさい C++でCの関数使うななんていう妄言には耳を貸さなくていい
>>201 得するわいカス
自前のクラスの入出力を自由にカスタマイズできるだろうが
printf()には到底無理です
でないとわざわざiostreamなんか作るわけない
C++でもputsはよく使います(笑)
sync_with_stdio()をtrueにしておかないと同時に使った場合の 動作は保証されないぞ
stdioしか使わないから問題ない
ios::sync_with_stdio() C の標準入出力操作と C++ のストリーム操作を同じ標準ファ イ ルで実行すると、同期の問題が発生します。入出力の各ス タイルではそれぞれ独自のバッファリングが行われるた め、 プ ログラムの実行順序と入出力の順序は異なります。この同 期の問題を解決するため、標準ストリー ム で あ る cin、 cout、 cerr、clog のいずれかに入出力を行う場合は、その 前にこの静的関数を必ず呼び出してください。この関数 は、 各 標準ストリームを stdiobuf を使用するように再設定しま す。これにより、標準入出力とストリームを介して行う入 出 力 が同期して行われます。パフォーマンスは、バッファつき ストリーム入出力やバッファつき標準入出力をそれぞれ単 独 で 行 なった場合よりもかなり低下します。 stdiobuf(3CC4) を参照してください。 注 : sync_with_stdio が必要になるのは、同じ標準入力ファ イ ル、出力ファイル、エラーファイルに入出力を行うときだ けです。 stdin 上で C の標準 (stdio) 入力関数を排他的に 使 用し、 cout 上でストリーム出力関数を排他的に使用する ことは、難しくはありません。
>>206 これは、例えば今回の
printf()
と
std::cout
を同時に使う場合にも
std::ios::sync_with_stdio()
が必要ということですよね?
>>201 まぁ気分はわからんでもないが、iostream も慣れると悪くないよ。
確かに細かいフォーマッティングするときは printf が使いたくなるが。
boostのformatってどうなんかね。
>>209 それなしでは生きていけない体にされました
>>202 >自前のクラスの入出力を自由にカスタマイズ
イミフ
>でないとわざわざiostreamなんか作るわけない
オナニ
>>211 >>イミフ
202じゃないけど、Effective C++読んだことある?
213 :
211 :2009/09/10(木) 12:03:56
>>212 なんか書いてあったっけ?stream 絡みは読み飛ばしてた。
昼休みに読んでみる。thx!
Effective C++でなくてもTCPLやD&Eにも書いてあると思う
Cの話題ではないけど、一般的に関数の引数順って Set( int &先, int 元 ); Copy( int 元, int &先 ); という感じなんでしょうか? それともどっちかに統一すべき?
私はmemcpyを参考にして(先,元)で統一してる つかC++的には先.copy(元)じゃないんだろうか
俺もmemcpy等にならって格納先を前にしてる しかしstd::copyは逆なんだよな・・・
Cでは前者、C++では後者。 わからなくなったら、Cではstrcpyを、 C++ではcopyを思い出すといい。
アセンブリ言語の場合、
Intel構文(MASM系)→元、先
AT&T構文(gas系)→先、元
となってる。
C++的には
>>216 じゃね。
C++的と言ってもマルチパラダイムすぎるからなぁ OOPだと dest.copy(src); とか dest = src; とか ジェネリックプログラミングだと copy( src.begin(), src.end(), back_inserter(dest) ); とか メタプログラミングだと typedef src dest; とか struct dest : src {}; とか まぁ統一感なんか皆無だから雰囲気に合わせて好きに汁
何でback_inserterとか書いたんだ俺 まぁいいか別に
>>221 確かに逆だな。
Intel構文(MASM系)→先、元
AT&T構文(gas系)→元、先
が正解。
224 :
215 :2009/09/10(木) 19:07:43
ふむふむ。 統一している人が多そうですね。 自分も自作のものは統一することにしときます。
ofstreamで書き出そうとしたファイルと同一名のファイルが既に存在している場合に エラーを吐くようにしたいのですが、適切なオプションがありません。 どのようにすれば実装できるでしょうか?
>>225 ifstreamで一度openして、ストリームの状態を確認するしかない
よくアトミックにっていう表現を聞くんですが、 それってどういう意味
229 :
228 :2009/09/11(金) 10:26:18
× それってどういう意味 ○ それってどういう意味でしょうか?
他の誰か (プロセスorスレッド) に割り込まれずにっていう意味 ここではファイルが無いことを確認してからそのファイルを作るまでの間に他のプロセスにそのファイルを作られてしまう事態
排他的に処理するというのに近いニュアンスなのですね。 ありがとうございます。
atomicは分割不能ってニュアンスだよ つーかアトミックな操作でぐぐれば一発
何のためにしたいんだかわかると代替案もでるよね。
例外を投げるときは、オブジェクトの状態を元に戻す。 と書いてあったのですが、元に戻せない場合どうすればいいのでしょうか? 例 //ファイルのようなものを2つオープンする void open() { FILE f1, f2; try { f1 = fopen(); } catch (exception &e) { throw e; } try { f2 = fopen(); } ←2つ目のオープンに失敗 catch (exception &e) { try { close(f1); } ←1つ目を閉じようとするが失敗 catch (exception &e { } ← 例外を投げるわけにもいかず、どうしていいかわからない } }
>>234 一般的に、ファイルクローズの失敗はオープンしていない状態に戻っていると思うが。
普通の例外とより致命的な例外(プログラム全体での続行不能を示す)を用意する 一言で言えば「致命的なエラーが発生しました」で落とせということ
try-catch しか使えないの? 戻り値見て判断できない? あるいは try-catch 使うにしても flag 使ってなんとかならん?
「致命的なエラー」を出すと営業マンが起こるんです。 「嘘でもいいから顧客の前でプログラムを止めるな」って。
責任取らされるフラグはtrueのままでいいの?
>>235 そうなの?
ディスクフルでクローズに失敗した場合
ディスクを開けてから再クローズとか出来ない?
>>234 少なくともOpen失敗の例外はthrow再スローさせるんだろうから、
Open直後のClose失敗は無視すればいいんじゃね?
醜いし、腕力系かも知れんが、1つずつ開けられることをチェックして、 一旦 close する。両方 OK ならば再度開けて操作に移るというのはダメ? 途中でディスクいっぱいになったり、他のプロセスが書き込んだりとかしたら 何があるかわからんが。その辺は状況によってどれがどこまで大事かというだろう。
>ディスクフルでクローズに失敗した場合 普通は、ディスクフルで書き込みに失敗したためにエラーを返すことはあっても クローズそのものができなくなることはない。
>>234 2つめのオープン失敗が外に投げられないと困るでしょ。
close(f1) の失敗はできれば標準エラーやログに出力しとく程度で、最悪無視だろうな。
処理が中断したんなら、どうせ f1 の指すファイルの中身がどうなってるか保証は
できないんだし、そこは対策を考えても無駄でしょ。
難しいねこれ
246 :
デフォルトの名無しさん :2009/09/11(金) 23:31:13
ttp://codepad.org/zASwhl4f このコード、codepadで実行させると上のリンクのように正常に動作しているようですが、
私の環境g++ (TDM-1 mingw32) 4.4.0ですと
0.1
-9.25596e+061
と表示されてしまいます。
どうすれば正常に動作させられるでしょうか?
よろしくお願い申し上げます。
>>246 それは、むしろその環境の方がおかしいってことない?
まさかと思って念のため試したが、Linux g++ 4.3.3 で0.1,0.1 になったよ。
248 :
246 :2009/09/11(金) 23:50:16
>>247 ありがとうございます。
codepadはg++ 4.1.2 だそうです。
g++ 4.4.0系が悪いか、私のWindows XPが悪いか。。。
249 :
246 :2009/09/11(金) 23:55:16
VC++では 0.1 0.1 になりました。 g++かTDMかMinGWが悪いということのようです。 同じ症状の方いらっしゃいませんでしょうか?
250 :
246 :2009/09/12(土) 00:02:05
VC++では、long doubleを指定しても実質的にはdoubleと同じでした。 すなわち std::cout << std::numeric_limits<double>::max() << std::endl; std::cout << std::numeric_limits<long double>::max() << std::endl; で得られる値に違いがありませんでした。
251 :
247 :2009/09/12(土) 00:17:46
>>250 Linux g++ で試したら違うね。x86_64, i686 どちらの kernel でも違って
1.79769e+308
1.18973e+4932
規格ではfloat<=double<=long doubleとしか決まってないから 極端な話、全部charと一緒でも規格準拠
253 :
247 :2009/09/12(土) 00:24:06
>>252 規格だけではわからないから、わざわざ試したんだよ。
VCはいつからか知らないけど、double == long double。 追い打ちをかけるように、x64ではFPU使わずSSE2で処理する方針。 FPUには32/64/80ビット形式があったが、SSE2には32/64ビットしかない。
>>246 x86のGCCってビルド時のオプション次第でlong doubleの大きさが12バイトとか16バイトとか変えられたはず。
libcとgccとでそこら辺が食い違っているとかないかなあ?
>>254 そりゃ無茶だろ
超越関数もSSE2で自前で計算するのか
クロック数多すぎるぞ
>>246 バグ有りで現在ほとんど使われていないと思われる
TDM-MinGW4.4.1で走らせたら
0.1
0.1
となりました
>>256 超越関数はFPUでやろうが
SSE使ってソフトでやろうが
速さは同じだよ。
>>259 誰もSSEに超越関数命令があるなんて言ってない
>>260 ソフトでやってFPU並みの速度が出るのか
(;¬_¬)ぁ ゃι ぃ。。。
どっかのサイトにSSE2で超越関数のプロファイル取った例書いてある? Windowsなら QueryPerformanceCounter() 使えば測定できるだろ
>>261 未だにFPUが速いと思ってるのか?
755 :デフォルトの名無しさん:2009/07/04(土) 06:45:45
マイクロコード実装のFPU超越関数命令使うより、
四則演算で書かかれた超越関数サブルーチンを使った方が速い。
intelのコンパイラなんて、SSE2未対応CPU向けコードでも
fsin命令は使わず四則演算で計算してる。
っていうか俺が適当作ったSSEのsin関数も FPUより速かった
>>264 だから文だけ書くならいくらでも書ける
証拠を見せてと言ってるんだが
>>265 単精度だろカス
倍精度の話してるんだよ
>>266 おまえどこまで馬鹿なんだよ
> intelのコンパイラなんて、SSE2未対応CPU向けコードでも
> fsin命令は使わず四則演算で計算してる。
これが証拠なんだが。違うって言うならおまえこそ証拠出してみろよ
嘘でも文書は書けるがな
自分で手を動かさないような馬鹿に教えるつもりは無い
>>267 Intelコンパイラ持ってないんだよ
どこかまとめサイトないのか
俺の肛門は世界中の女子まんこより気持ちいい そういってるのと同じ。
>>250 せっかくなのでうちも。
環境
kernel.i686 2.6.18-128.1.14.el5
gcc-c++.i386 4.1.2-44.el5
出力
1.79769e+308
1.18973e+4932
>>270 試してみた。
vc8
precise 4.23 mmx
fast 3.44 fsin
intel 11.1
precise 3.19 mmx
fast 2.77 mmx
#include <iostream>
#include <cmath>
#include <boost/progress.hpp>
int _tmain(int argc, _TCHAR* argv[])
{
double x=argc;
{
boost::progress_timer t;
for(int i=0;i<100000000;i++)
x=sin(x);
}
std::cout<<x<<std::endl;
return 0;
}
floatでやるともっと速くなるかも。
275 :
246 :2009/09/12(土) 11:21:06
>>251 ありがとうございます。
どうやらg++はlong doubleをまともに導入しているようですね。
>>252 それは存じ上げておりますゆえ
std::cout << std::numeric_limits<double>::max() << std::endl;
std::cout << std::numeric_limits<long double>::max() << std::endl;
として確認したものでございます。
>>255 なるほど、その可能性はあるかもしれません。
探ってみます。
>>257 ありがとうございます。
TDM-MinGW4.4.1ですか・・・あまり入れたくないですね。
>>272 ありがとうございます。
276 :
246 :2009/09/12(土) 12:36:59
解決しました。 TDM-MinGW4.3.3 -> × TDM-MinGW4.4.0 -> × TDM-MinGW4.4.1 -> ○ ということで、 TDM-MinGW4.4.1で修正されたバグだったようです。 どうもありがとうございました。
MyClass x, y; 処理1(x, yを変更する。) MyClass z, w; 処理2(z, wを変更する。) としたいのですが、最初からまとめて宣言して MyClass x, y, z, w; 処理1(x, yを変更する。) 処理2(z, wを変更する。) とした方が処理速度的に良いってことはありますか? また、 MyClass hoge[4]; 処理1(hoge[0], hoge[1]を変更する。) 処理2(hoge[2], hoge[3]を変更する。) とした方が処理速度的に良いってことはありますか?
ほとんど一緒かと 実際に遅くて困ってて、そこがボトルネックだと判明したんでもなければ、そんな細かいこと気にしない方がいい いちいち気にしてたらプログラミングが進まない 普段は読みやすさを優先するべき
279 :
277 :2009/09/12(土) 22:34:14
>>278 > 普段は読みやすさを優先するべき
分かりました。
ありがとうございます。
可読性を優先していこうと思います。
C++を勉強中なんだけど、メンバ関数ポインタとデリゲートの違いがよく分からない。
http://www7b.biglobe.ne.jp/~robe/pf/pf016.html ここによると、特定のクラスに依存せずオブジェクトも保持できるように書いてるけど、
templateや、安全面には気を使うという前提でvoid*を使うとかで依存させずに
オブジェクトはメンバ変数で持つとかで対応できるような気がする。
JavaやC#で実装されてるので何かしら便利だと思うんですが何か違いがあるんですか?
JavaやC#には関数ポインタがないから、便利とかいうより他にやりようがなかろう?
>>280 メンバ関数ポインタは this ポインタを与えてやらないと呼び出せない。
「〜で対応できる」の部分については、 boost::function (および次期標準規格の
std::function )がその役割をカバーしている。 boost::function が「デリゲート」に近い。
>>280 メンバ関数ポインタとデリゲートは目的は似てるといえるけど実装方法が違う。
C++でC#のデリゲート相当を使いたい場合は関数オブジェクトの使い方を勉強すると良い。
さらにboost::function boost::bind boost::signals2を使うとC#のデリゲートやイベント構文相当が簡単に使える。
C++は、(Cのような)グローバルな関数・静的メンバ関数とメンバ関数とでポインタの扱いが異なるのが面倒。 C#のデリゲートは静的なメソッドもそうでないメソッドも同じように代入できるのがいい。 (もちろん、共に引数・戻り値の型が程度はともかく合っていないといけないけど) そして、C++でもその手の仕組みを書けば、全部共通して扱えるのが便利。 普通はbindとfunctionを使うけど。
>>276 そんな bug があるって恐ろしいね。使いたくない環境だ。
確かにTDM 4.4.0はもうDLできないようにされてしまってるから バグなんだろうなあ
287 :
246 :2009/09/13(日) 00:13:28
288 :
280 :2009/09/13(日) 01:42:37
なるほど、関数オブジェクトですか… よく分かんないからとばしたんですよね、ちょっと勉強してみます。
C++のABIについて詳しく書かれた書籍を教えてください。
>>287 coutが対応していないだけでは?
数値はあってるけど、ふつうにdoubleとして出力しているとか
関数オブジェクトなんてここの1レスで説明できるくらい簡単だと思うがなぁ。 // 関数定義例 int add ( int x, int y ) { return x+y; } // その呼び出し例 int a,b; add(a,b); これが、関数オブジェクトだと // 関数オブジェクト定義例 struct add { operator () ( int x, int y ) { return x+y; } }; // その呼び出し例 int a,b; add()(a,b); // 別の呼び出し例 int a,b; add f; f(a,b); 違いは、関数がオブジェクトになること。 例えばsortテンプレートに比較関数を与える場合、関数ポインタを与えると関数コール が生成されるが、関数オブジェクトを与えるとインラインで展開される可能性が高く、 比較関数のような小さいコードではインライン化の利得が大きい。 まぁ述語関数オブジェクトには罠もあって、状態を持つような関数オブジェクトだと 関数オブジェクトのインスタンス自体をコピーしてしまうテンプレートアルゴリズム では問題が出たりする。とはいえ、基本的には簡単な概念だ。
292 :
280 :2009/09/13(日) 07:47:29
>>291 うん、なんかすっげー簡単だね。難しく考えすぎてたみたい。
でも、自分のしたいことはクラスの特定のメンバ関数を別のクラスに渡したいんだけど、
これは、メンバ関数ポインタかデリゲートを使うところだよね?
渡すってのが何をしたいんだか分からんけど、ポインタ的に渡すならboost::function でいいんじゃね
294 :
280 :2009/09/13(日) 08:02:45
そうそうポインタ的に渡したい。 でも、boostは使えない環境なので何とか自分でやってみます。
>>292 ロベールで言えばChapter13という事になるが、出来ないんじゃね?
メンバ関数を呼び出すにはあくまでもthisポインタが必要なので、
オブジェクトのインスタンスがどうしても必要になる
それだったらメンバ関数へのポインタを他のクラスに渡すという考え方を
やめて、コンポジションで処理すべき
>>292 特定のメンバ関数を呼び出す関数オブジェクトを作って渡せば可能。
関数オブジェクトを作るのが面倒なら、boost::bindを使うと関数オブジェクトを
式内で簡単に作ってくれる。
>>296 済まないがboost::bindを使わないでやるサンプルコードを
簡単な物でいいからCodePadに貼って欲しい
どうしても概念が理解できない
>>297 それこそ
>>280 のページのIFoo/CFoo。
attach(Foo(this, &Test::hoge));をbindで書き直すとattach(bind(&Test::hoge, this))となる。
別にメンバ関数ポインタでもいいんじゃよ
ちなみにboost::functionのソースは相当難解だから、色々な前提知識無しにいきなり 読んでも多分挫折する
>>297 bindを使いたくないなら関数オブジェクトで十分同じことができる。
>>301 継承は実現するための1つの手段。それ以外のやり方もある。
>>297 bindとfunctionのサンプル書いてみた
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class Hoge
{
public:
void print(int a,int b){std::cout<<"a="<<a<<" b="<<b<<std::endl;}
};
template<class F>void Fuga(const F& a){a(200);}
void Huga(const boost::function<void(int)>& a){a(30);}
int _tmain(int argc, _TCHAR* argv[])
{
Hoge a;
Fuga(boost::bind(&Hoge::print,&a,_1,100));
Huga(boost::bind(&Hoge::print,&a,_1,90));
boost::function<void(int)> f=boost::bind(&Hoge::print,&a,50,_1);
Fuga(f);
Huga(f);
return 0;
}
>>294 ちなみに、新しいg++とかVC++とかだと標準でbindもfunctionも付いているよ。
そうでないなら仕方ないけど。
関数オブジェクトも「それを使ったサンプルを作ろう」と思うと使えるのに、 アプリを書いているときに自然には書けないんだよな。 未だ自家薬籠に入ってないらしいw
ゼロオーバーヘッドを目指すと自然に関数オブジェクトに辿り着く時はある
>>304 こりゃまたエラい見た目簡単そうなコードになりますね
コンパイルすると引き延ばされて大きくなりそうだけど
結局最適化で小さくなるなら問題なし
>>307 functionはテンプレート関数にしなくてもファンクタが渡せて便利な分、
TypeErasureのために関数ポインタか仮想関数分のオーバーヘッドがあるってことだね。
311 :
280 :2009/09/13(日) 10:55:47
いろんなとこからパクってるとこだな まぁ見やすいし便利ではある ただしやね信者
たまには、boost総合スレを思い出してください。
315 :
280 :2009/09/13(日) 15:55:29
typedefでのtemplateって出来ないんですよね? 仕方がないからdefineでやるしかないのかなぁ。
C++0xでできるようになるらしいから、あと1年まとうぜ。
そう…ですか。それまでdefine様にすがってます。
>>316 C++0xはあと3〜4ヶ月程度で本当に出来るのか?
まさかとは思うが
C++0fまでokとかじゃないよな?
C++0xの一部の機能は既に実装され始めているからそう悲観するなって
320 :
デフォルトの名無しさん :2009/09/13(日) 17:51:50
テンプレート引数としてクラステンプレートを渡す時、 閉じカッコが >> となると左ビットシフト演算子と同じになって…(ry ってのは、C++0xでは例外的に認める方針で解決されるんだっけ?
C++0xでは>>の閉じ括弧は仕様になったよ。現在のコンパイラでも使えるものもあるよ。
323 :
デフォルトの名無しさん :2009/09/13(日) 18:48:15
二次元配列の演算子オーバーロードって出来るんですか?
>>318 禿はC++10か11になるだろうとどこかで言ってた気がする
>>323 二次元配列の演算子というものは無い。[]演算子を2個組み合わせて二次元配列を作っている。
[]演算子そのものはオーバーロードができるのでこれを同様に2個組み合わせることになる。
具体的に言うと一個目の[]で2次元配列から1次元の配列を返し、それを2個目の[]で要素を返すようにする。
>>325 実装の仕方がわかりません。
T &operator[](int i, int j) const { 中身省略 }
これだとエラーになるんで。
>>326 []演算子の引数は1個だけ。AというクラスでBというプロキシーオブジェクトを返し、Bオブジェクトから要素への参照を行う。
class A{
public:B& operator[](int i){省略}
};
class B
{
public:
int& operator[](int j){省略}
};
int s=a[100][100];
libjpegというフリーのライブラリを使ったソフトを配布(ソースは配布せず、.exeのみ)したいのですが、
ライセンス表示をどのようにしようか迷っています。
ttp://www.syuhitu.org/other/jpeg/jpeg.html >バイナリのみで配布するのなら、どこかに
>"this software is based in part on the work of the Independent JPEG Group"
>という記述を加えること。
今、考えているのは以下のどちらかなんですが、
A:ソフトを配布するWebサイト上でのみライセンス表示する
B:配布ソフトといっしょにReadMe.txtとかLicense.txtみたいなファイルを付けて、
そこにライセンスを記述する
Aってマズいでしょうか??
331 :
329 :2009/09/13(日) 20:50:55
>>330 失礼しました。
こういうのって、どのスレで聞くべきなんでしょうか?
333 :
329 :2009/09/13(日) 20:54:42
334 :
デフォルトの名無しさん :2009/09/13(日) 23:07:53
C++0xのstatic_assertに対応しているかどうかを マクロで調べたいんですが、 どうすれば良いか教えていただけますでしょうか? つまり #ifdef C++0xのstatic_assertに対応している static_assert( CONSTANT-EXPRESSION, "error-message" ) ; #else assert( CONSTANT-EXPRESSION ) ; #endif としたいのです。 BOOST_STATIC_ASSERTは訳あって使えないのですが、 よろしくお願い申し上げます。
>>334 static_assert はコア言語の機能で、マクロはプリプロセッサのものだから、無理。
次期規格で __cplusplus の値が更新されたりすれば使えるかもしれないけどね。
そもそも static_assert() は assert() で代用できるようなもんじゃないし、
BOOST_STATIC_ASSERT が使えなくてもコンパイラさえ限定すれば自前で実装しても
たいして難しくないよ。
336 :
334 :2009/09/13(日) 23:36:23
>>335 なるほど、そうですか。
どうもありがとうございました。
337 :
334 :2009/09/14(月) 00:27:38
ttp://codepad.org/elvsrpFF とりあえずconst bool型のコンパイル時定数のみに
対応させたmy_c_assertを作ってみました。
しかし、これではまだ
typedef MyNS::my_c_assert<yyy> piyo;
の部分もコンパイルが通ってしまいます。
piyo p;
としておけば
aggregate 'main()::piyo p' has incomplete type and cannot be defined
の様に言われてコンパイル時エラーになるのでいいのですが、
それだとtrueの場合に
hoge h;
に対して
warning: unused variable 'h'
と言われてしまいます。
ここからどうすればfalseの時だけコンパイル時エラーになり、
trueの時はwarning: unused variableが出ないように出来るでしょうか?
よろしくお願い申し上げます。
339 :
デフォルトの名無しさん :2009/09/14(月) 12:33:53
340 :
デフォルトの名無しさん :2009/09/14(月) 13:14:22
俺は電車が好きで、中学生のころ よく8つ離れた兄のところへ新幹線でいったんだ。 ちょっと高いからだけだからって、時々とうちゃんがグリーン車の代金をくれて 乗っていったんだが、そのたびに周りの客に「生意気ながきだ」みたいな目で見られて。 そういう大人にはならないどこうと肝に銘じたもんだ。
341 :
デフォルトの名無しさん :2009/09/14(月) 14:33:36
placement newでクラスインスタンスを配列で生成しようとしたのですが、 void *vp = malloc( sizeof(T) * count ); T *tp = new(p) T[count]; これだと確保したメモリ領域の先まで上書きされるようなんです。 これはどうしてでしょうか? また、どのように解決すればいいでしょうか?
new(vp)じゃねえの 単なる写しミス?
>>342 書き間違えました
それが原因ではないので気にしないで下さい
確保した領域の先まで書くようなコードになってるんじゃないの?
>>344 newの段階で書き込みが発生しました。
347 :
デフォルトの名無しさん :2009/09/14(月) 15:11:44
>>341 一般にnew T[N]はsizeof (T) * Nと同じだけのメモリを使うわけではない。
delete[]のときのため要素数を記録する分多くメモリを使う。
new(p) T[count]の場合もそうだと思う。
forなどで、new(p + sizeof(T) * i) T;などとすればいいと思う(pはchar型にでもして)。
ちなみに、forを使わずともuninitialized_fill_nなんかでもできる。
>>341 短く言うとnew T[N]で必要な領域はsizeof(T)*Nじゃないから
配列形式のplacement newはC++の暗黒面だから諦めたほうが良い。
alignment_ofとかあるんだよな…
struct str{ vector<a> vec; }; list<str> lst; こんな感じでlistの中にvectorを使っている場合の削除について質問なんですが、lstでeraseまたはclearをすると vectorではclearとかはしなくていいのですかねぇ。それともしたほうがいいの? しなくてもメモリリークは起きなかったけれども
しなくていい
>>341 配列のplacement newはには何らかの情報が追加として必要になる。要素数の場合が多いであろうが決まっていない。そのため確実に動作を保証できないので使わないほうがいい。
実際は、多めにとったメモリブロックに普通のplacement newを実際に必要な数だけforしたほうが効率がいい。
質問です。 同じプログラムをコピーして、同じVC++でコンパイルしているのですが、片方ではコンパイルできて、もう片方ではエラーが出てくるような場合は何が原因として考えられるでしょうか? よろしければ自分で調べるヒントになるようなキーワードなども教えていただけるとありがたいです。よろしくお願いします。
まずはエラーメッセージを貼ることから始めよう。
せめてどんなエラーなのかくらい書かないと何も分からんだろうがボケナス そんなだからお前のコードは後で読めなくなるんだ
>>355 >>356 申し訳ありませんでした
error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
warning C4183: 'd1': 戻り値の型がありません。'int' を返すメンバ関数とみなします。
error C2236: 予期しない 'class' 'c2' です。';' が入力されていることを確認してください。
error C2143: 構文エラー : ';' が '{' の前にありません。
error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?)
以上です。エラーが出ないほうのソースをコピーしても、コンパイルできないほうに全部貼り付けてみても無理でした
どうかよろしくお願いします
どっかでinclude忘れてね?
stdafx.hをコンパイルオプションでインクルードしてるケースもあるな
>>358 コピーしてきてるので、忘れてるということはないと思います。(コピー範囲もちゃんとチェックしました)
>>359 具体的にどういうことでしょうか?
最初にエラーの起きた行の周辺も必要かな。
例えば、片方のプロジェクトのオプションで、 構成プロパティ→C/C++→詳細→必ずインクルード のとこの設定が違ったりするとか。 まぁでもぶっちゃけまだ情報不足。エラーの出た行とその前後くらいは欲しい。 識別子が型として認識されてない時のエラーに似てるから、インクルードされてない のかな、と思った程度で、結構エスパー訓練状態。
>>361 レスありがとうございます。6行目、12行目のエラーなのですが、
1: #include <selen.h>
2:
3: nt WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
4:
5: using namespace Selene;
6: const Point2DI SCREEN_SIZE( 640, 480 );
7:
8: Engine::ICore *pCore = NULL;
9:
10: //エンジンアクセス用のコア生成
11:
12: #ifdef SLN_DEVELOP
13: if ( !Selene::InitializeEngine( L"Selene.Develop.dll" ) )
14: #else
15: #ifdef SLN_DEBUG
16: if( !Selene::InitializeEngine( L"Selene.Debug.dll" ) )
17: #else
18: if( !Selene::InitializeEngine( L"Selene.dll"))
19: #endif
20: #endif
{
goto EXIT;
}
いちおうSeleneというのはこちらのことです
http://selene-lue.halfmoon.jp/document/Engine/index.html http://selene-lue.halfmoon.jp/document/Utility/index.html
どうしてプロジェクトファイルはコピーしなかったのはなぜ?
>>364 とくに理由はないのですが、強いて言うなら新しくSeleneというものを使ってみようと思い、自分でやってみました
そのインクルード、パスはあってる? 右クリックで開けるか確認した方がいいかも
>>366 開くことができました
すいません、今自分でも模索してたところでした
確かにplacement newの配列版はC++の暗黒面だわ 予め正確なサイズを知る事が出来ないわけだからなあ
カツカツにしなければよいのではないの?
すいません、いまだにできません。 仕方ないのでいったん断念します。考えてくださった方ありがとうございました また何かあったらよろしくお願いします。
さすが東方厨
>>369 要素数値の領域が何バイトとられるかも決まってないから
たとえ要素の並びのいっこ前が要素数だとしてもどこから配列として使えるのか分からない
それに要素の並びの1つ前が要素数だと決まってるわけでもない
ってことでムリっぽい
ヲタへ話を広げんな
>>372 カツカツじゃなくてもまともに動作する領域をくれないということ?
377 :
デフォルトの名無しさん :2009/09/15(火) 21:15:13
>>341 の事象がよくわからないのですが。
↓のコードでは特に問題ないよう。
何が間違ってますか?
#include "stdafx.h"
#include <iostream>
#include <new>
static int g_size = 0;
class T
{
int a;
public:
static void* operator new (size_t size, void* buf) throw(){g_size+=size;return buf;}
static void operator delete (void* buf) throw(){;}
static void* operator new[] (size_t size, void* buf) throw(){g_size+=size;return buf;}
static void operator delete[] (void* buf) throw(){;}
};
int _tmain(int argc, _TCHAR* argv[])
{
int count = 2;
void *vp = malloc( sizeof(T) * count );
T* i = new(vp) T[count];
delete [] i;
std::cout << g_size << std::endl;
return 0;
}
>>377 デストラクタを持たせてみると落っこちるかもしれない。
あるいは、お前の実行環境ではちょっとくらい確保した量を超えての読み書きが許されていて、何も起きないのかもしれない。
>>378 確かにデストラクタを入れたところ、freeで落ちました。
そこで、確保するヒープのサイズを適当に増やしたところ
落ちなくなりました。
それ以前に、newを呼び出したとき先頭4byteに個数が
入っているのを見落としていました。
理解しました。ありがとうございました。
380 :
デフォルトの名無しさん :2009/09/15(火) 23:06:50
1はない。 2が無難。 速度的には3かな?
速度的には3。 ただこれもまだ高速化の余地がありまくる。
オブジェクトがオブジェクトに命令を与えるのがオブジェクト指向って何処かで見たけど つまり とあるクラスの実体Aが、別のクラスの実体Bに命令を出して 実体Bはその命令に従ったメンバ関数を実行する って事で良いの?
384 :
380 :2009/09/15(火) 23:50:22
>>381-382 ありがとうございます。
3で行こうと思います。
> ただこれもまだ高速化の余地がありまくる。
すみませんだいぶ無理のある例で。
あくまで例のためのソースでして、ご容赦ください。
>>383 別にそれだけじゃないとは思うけど、
醍醐味はそうだろうね。
>>380 これじゃいかんの?
--
std::string foo(unsigned int num, const char * const ptr)
{
return std::string(ptr, ptr + num);
}
>>386 ちょっと類似した件のための例ですので。
実務でしたら、私だったら
std::string(ptr).erase(num)
の1行で終わらせます。
いや一行なら
>>386 さんのおっしゃる通り
std::string(ptr, ptr + num);
の一行の方が美しいですね。
ありがとうございます。
ですがあくまで例のためのソースでして、ご容赦ください。
>>385 うーん。
命令を出すって言うのがいまいちパッと来ないで困る。
プログラムで簡単なサンプルとか無い?
ピタゴラスイッチ
C++は力を得る為にあらゆるものを取り込んだ怪物だから、全面的にOOPで書くのは 異様。アルゴリズムと型の分離という抽象化も平気でやる言語だし。問題に合う方法論 を自由に選べるのがおいしい訳で、一つの方法論だけでやってくとおいしくない。 オブジェクトがオブジェクトに命令を送ってメンバ関数を、って形態をC++で素直に 表してるのは仮想関数のディスパッチあたりだろうけど、仮想関数じゃないなら単に 「メンバ関数コールは命令送出そのものである」くらいのシンプルな捉え方でいい。 つーか「全てがオブジェクトである」というタイプのOOPじゃないから、そういう世界 の話を持ち込むと混乱しがち。純OOPで表現しようとすると逆に複雑で訳分からなく なることも多いし。そもそも標準ライブラリが純OOPじゃないし。
使えそうならどんなスタイルでもやっちまうので結果カオスに でも劇団「プロジェクトひとり」ならマイモンタイ
関数型以外で末尾再帰とかほとんど書かないのと同じことだよ。 OO特化言語でもなければ、オブジェクトと非オブジェクトが混在するのは自然だし、 設計に問題がある訳でもない。
void F( std::string &s ){ size_t size = data_size; s.resize( size ); memmove( s.c_str(), data, size ); } これって有効な操作? ようは、渡されたsに対して、新しい文字列を割り当てたいんだけど。
>>396 c_str()は読み取り専用だったはず。
std::string::assign()を使えよ。
398 :
デフォルトの名無しさん :2009/09/16(水) 18:48:52
>>396 そもそもstringのc_str()で得られる内部の配列は、連続していることが保証されてないからダメだよ。
ああ、新し過ぎるな
stringの内部バッファの連続性が(今のところ)保証されてないのはその通りだけど それと勘違いしてるんじゃないの
あるテキストファイルの内容を読み込むときに、 改行コードまで読み込むにはどうすればよいでしょうか? 今はgetlineでやっているのですが、読み込んでくれないようです。
自分でくっつければいいじゃん \nか\r\nかを見たいなら、そもそもテキストとして扱うと勝手に変換されちゃうから バイナリモードで開いて直接探索するしかない
なるほど見透かされてますね。 ありがとうございます。バイナリで開いて頑張ってみます。
>>392 次世代の怪物Scalaはどうよ
JVM上でhlistが実装できるぜ
JVMを使うならJavaで十分
Javaで十分な人はそれでいいんじゃね scalaは今後どんどん注目されるだろうな アクターモデルとかすばらしい
VMの鬼もっさりが解消されれば別だけど、携帯すらネイティブコードに向かってる ご時世だからなぁ
>>408 VMって結局インタプリタだしオーバーヘッドは大きいよな。
JITだといっても実行時にコンパイルするってオーバーヘッド大きすぎ。.NETなんか
初めて開くダイアログなんか遅すぎるよね。
いや、一応Crusoeみたいに動的にボトルネックを探して最適化するから、ただの インタプリタじゃない。 とはいえ、結局は重い。Crusoeと同様に。 ボトルネックの負荷が激しいなら、激しくヘタクソなC++コードよりは高速動作 することもある。海外にそんなブログがあって、どっかのスレで念入りな検証を されてボコられてたが。
JAVAはGCの結果効率的にオブジェクトが配置されるため高速化されることが期待できる からネイティブより速くなることがあるとか読んだことがあるけど、実際どうなのかな。 それなら最初からメモリ配置を設計できるネイティブ系の言語のほうがいいような気もするけど。
Googleの誰かが「将来はVMの方がネイティブコードより軽くなるかもしれない」と 講演で言ってたみたいだけど、現時点では遙かに遠い話に見えるなぁ。 Crusoe系列が生きていたら将来Core系列に勝てるようになっただろうか、という 想像に似ている気もする。 ただ、VMの方がマルチコアで慢性的に余ってるスレッドを活用しやすいから、それを スカウトスレッドやら投機的MTやらに活用するようになってきたりしたら、逆転は 十分にあるな。 まぁその時は、乗り換えてもいいし、C++/CLIでVM使ってもいいし、両方使い分け もいいし。JVMもCLIも大体同レベルで進歩するだろうから。
>>412 ふーん、そんな予想が立ってるのか。
しかしそんな将来なら今度は
> マルチコアで慢性的に余ってるスレッドを活用しやすい
これをネイティブコードで解決する技術が出現してくるんじゃないかと思われる。
まぁでもGoogle所属の人ってだけだし、予測が外れるなんてごく普通だからなぁ
>>411 次々期C++がGCを取り込もうとしてるのはその辺の関係もあるのかもしれないな
質問なのですが、 sizeofって文脈によって意味が変わりますよね? sizeof("hoge")では何が返るとか、 そういったsizeofの使い方はどこで分かるのでしょうか? よろしくお願いいたします。
>>45 型が指定されれば、メモリ上でその型のオブジェクトが占めるバイト数。
値が指定されれば、その値の型について上記と同様。
変わるっていってもこの2つだけでたいした違いはないはずなんだけど、
何か勘違いしてない?
>>415 つまるところ、文脈によって意味が変わるのではないかという勘違いをしてるだけじゃないかなぁ
>>416 あれ?その2つでしたか。
いまいちとらえどころがないなぁと思っていたのですが。
ありがとうございます。
419 :
416 :2009/09/16(水) 23:34:42
もしかしてこれか? int a[3]; sizeof(a) 配列全体のバイト数 int* a; sizeof(a) ポインタのサイズ
>>420 まさにそれです。。。
配列が絡むと何を返してくるのかよく分からなくて。
しかしその2つの対比をしてくださったおかげでちょっと納得した気がします、
422 :
デフォルトの名無しさん :2009/09/16(水) 23:55:15
全然関係ないけど、
sizeof - Wikipedia
ttp://ja.wikipedia.org/wiki/Sizeof に
> 厳密な大きさはsizeof(char)が1であることを除いて標準に定められていない。
って書いてあるけど、sizeof(char)が1ってホント?
俺の記憶では確かsizeof(char)すら処理系依存だったと思うのだが。
1がバイト数とも限らないってことじゃないか?
>>421 やっぱり勘違いだね。
ポインタはポインタのサイズであって、ポインタが指す内容のサイズではないですよ。
>>422 1byteが8bitであるとは限らないという話と混同してないかい?
1バイトは8bitとは限らない
426 :
422 :2009/09/17(木) 00:04:36
それだ!! ありがとう!
VMの話ならLLVM。 「VM(笑)遅いし」ってのは過去になりつつある。
#define HOGE(*****) ***** ってなマクロを、確か二重にしているのを見たりするんですが、 これって何のためにやっているのですか? 特定のコンパイラ向けとかでC++でも実際にそうしておく必要がありますか?
>>428 マクロにマクロを渡すみたいなことをやり始めると、一重二重で意味が変わってくる。
紙幅が全く足りない上に俺もそこまで詳しくないのでプリプロセッサの仕様読んでくれとしか
#define ABC XYZ #define CONV_TO_STRING(x) #x #define CONV_TO_STRING_EXPAND(x) CONV_TO_STRING(x) ABC CONV_TO_STRING(ABC) CONV_TO_STRING_EXPAND(ABC) -----プリプロセッサを通すと------ XYZ "ABC" "XYZ" --------------------------- これのこと?
431 :
428 :2009/09/17(木) 20:50:17
ありがとうございます。 それです。 BOOST_PP_STRINGIZE の実装でもそうなっているようですが、 正式なプリプロセッサの仕様はどこで学べるのでしょうか? そして学んでおく必要はありますでしょうか?
>>431 >正式なプリプロセッサの仕様はどこで学べるのでしょうか?
つ[google]
>そして学んでおく必要はありますでしょうか?
必要ないよ、そんな質問をするような間抜けには。
433 :
デフォルトの名無しさん :2009/09/17(木) 21:09:35
大丈夫、私は私が必要と思うことを学んでいるから。
436 :
428 :2009/09/17(木) 22:18:16
>>435 ありがとうございます。
さっそく”プログラム言語C”(JISX3010)を見に行ってきます。
奥が深いですね、Cプリプロセッサは
既存のコードの理解に必要ならしょうがないが、プリプロセッサの サーカスやってるとミスの確率も高くなるし、後でわからなくなるよ。 あと、C++ ではむしろ C プリプロセッサの複雑な部分を普通使う 必要も無いし、使わない方が良いと思う。
Boost.Preprocessorとか専用のライブラリを使うとミスは少なくなるし 可読性も(素でやるよりは)うpするよ
残念ながらまだまだガチのメタプログラミング(マクロも含めた意味で)では プリプロセッサの必要性は残る。Boostの実装もBOOST_PP使いまくりだったり するしな。 C++0xはその辺の実装経験も元に、さらにプリプロセッサの必要性が下げられる 見込みだけど。
>>440 BOOST_FOREACHやBOOST_AUTOは有用なプリプロセッサだけどc++0xではサポートされるしな。
プリプロセッサは基本的には、使うべきじゃないとは思っている。
しかし、膨大な繰り返しをミスなく記述するような有用に使うのは問題ないと思う。
例えばVisitorを使うには派生関係の無い似たような関数をたくさん作る場合など。
メタプログラミングはエラー特定しにくいだろ。 なるべく使わず済ませよ。
つ再利用性
コピペで大量生産するならメタプログラミングを選ぶ
いいか、同じコードは2度書くな。鉄則だ
いいか、同じコードは2度書くな。鉄則だ 重要なことなので2度言いました。
いいか、同じコードは2度書くな。鉄則だ やっべ、車輪の歳発明またやっちまった
再発明と言うより、バグ、デバック減らせるのが大きい。 しかし、メタプログラムはバグがわかりにくい。 なるべく使わず済むようにすべき。 使うならそこだけヘッダにして分割するとかが良い。
メタプログラムは一度バグを乗り越えたら、修正が楽だし再利用性も容易になる。 メタは少しずつ階層を増やしながらコンパイルで確認しつつ書くのがいいかも試練。
メタプログラミングはその利点に乏しい 利点より欠点の方がおおいよね?
コンパイラのようなメタプログラミングの塊みたいな分野もある あと外部ツールでコード生成するのも一種のメタプログラミングといえよう 後者の技法を使ってるプロジェクトは数え切れないぐらいあるだろう その事実を以ってすれば欠点の方が多いと言い切ることは不可能である
完成品を利用するならいいが、バグ取りの時点では、不利。
>>450 無知?
まあメタプログラミングは天才にやらせてその成果物を凡人が使う。
これが鉄則。うん。
確かに自分でメタプログラミングしようという気にはならない というか再利用可能なクラスですら書きたくない もちろん信頼できる第三者の成果物はメタもクラスも利用するよ!
メタプログラミングを本来の意味で言ってるのか、テンプレートメタプログラミングの ことを言ってるのか分からん
メタプログラミング2.0が出たら本気出す
ポインタ分からない人に限って「ポインタは一応分かってるけどあんなもの危険だし 不要だよ」と言うもんだ。
>>454 俺、自分よりboostや他企業の製品のが信頼できる。
>>458 自社製品は怖くて使えない・・・
これが世の共通認識w
>458 あれ、俺いつの間に書き込んだっけ?
C++で、ソースコードのコメントに hogeクラスは…(ry と書くのと クラスhogeは…(ry と書くのと、どっちがいいのでしょうか? JISとかで決まっていますか?
463 :
デフォルトの名無しさん :2009/09/18(金) 11:38:28
>>462 ありがとうございます。
hogeクラスは…(ry
クラスhogeは…(ry
とどっちがJIS等で正しい用語か決まっているでしょうか?
答えになってないが、個人的な感覚では hogeクラス → hoge というタイプのクラスがある。 クラスhoge → クラスの名前がhoge。 という感じがする。
>>464 あーなるほど、
入出力クラス と class MyIO
みたいなかんじですね。
466 :
464 :2009/09/18(金) 12:18:26
え、hogeにそれを当てはめちゃうのか class hoge についてだと思ってたのに。。。
468 :
464 :2009/09/18(金) 13:45:35
>>467 あ・・・確かにそうですね。。。
class hoge についてはもしかして違うかもしれませんね。
ところでお前は464じゃないだろう
470 :
461 :2009/09/18(金) 13:49:46
すすす・・・すみません。 悪気は全くありませんでした。
471 :
461 :2009/09/18(金) 13:56:25
珍しく丁寧な人がw なんだかこちらこそありがとう
誤爆にエスパーレスすると永沢くんのほうがわかりやすくね?
黒幕はアガサ博士
PDH.DLLについて質問なのですが、PCが高負担時(CPU或いはHDD読み書き?)にPdhCollectQueryDataを呼び出すと、 呼び出した側のプロセスの全スレッドがカタカタとラグが起こったように固まってしまいます。 PDHの内部に生成されるスレッドの優先度を上げてみては直るのではと考えて色々調べたのですが、PDHはプロセスではないためスレッドハンドルを取得する方法がわからず挫折しています。 PDHのラグ対処法、あるいはモジュール内のスレッドハンドルの取得方法をお知りの方がおられましたら教えていただけないでしょうか。 以下問題が起こる処理のサンプルです。よろしくお願いします。 PdhOpenQuery( null, 0, &hQuery ); PdhAddCounter( hQuery, "\\Processor(_Total)\\% Processor Time", 0, &hct ); ループ { PdhCollectQueryData(hQuery); PdhGetFormattedCounterValue( hct, PDH_FMT_LONG, null, &value ); printf( "%d\n", value.longValue ); Sleep(50); }
なんていうか、この処理自体は別スレッドで動いてると思えばいいの?
Win32API?だったらWin32APIスレが的確だよ
ああそういえばそんなスレもあったなと思ってのぞいたらカオスだった。 こわいよう
スレ違いすみません。カオスなのですか…どうしよう。 別スレッドを作成してループさせても、main関数内でループさせても固まる現象は同じでした。
482 :
479 :2009/09/19(土) 09:24:14
>>481 本当にカオスだったな。すまんかった。
OS標準のパフォーマンスログも高負荷時にサンプルできなかったのエラーメッセージ
が出るくらいなので、APIが詰まるのはしかたないような気がするね。
APIの実行が遅れてもいいようにAPIの実行間隔を計測すればいいかもしれない。
プロセス内の他のスレッドに影響出るのはよく分からない
OS標準のパフォーマンスログですらエラーになるのですね! って事は、そもそもスレッド優先度云々の問題ではないのですね。 とてもすっきりしました。ありがとうございます。 とにかくコレクトが固まるのはあきらめて、別スレッドに影響でる原因の方を調べてみる事にします。 本当に迷走していたので助かりました。 改めて感謝です。
何か同じリソースを激しくアクセスしてブロックが起きてないかを確認するのもいいかもしれない。 レジストリとかファイルとか
485 :
デフォルトの名無しさん :2009/09/19(土) 14:55:13
struct float3{ float x, y, z;} float3 v0; float3 v1 = v0.zyx; float2 v2 = v0.yz; こういう風に記述したいんですが、メンバ関数「zyx()」等を作る以外で 何か方法はありませんか? VisualC++なんですが、MSCコンパイラ依存拡張を使っても問題ないです。
ないと思う
>>485 C++ の悪魔が、ふいにこんな変態コードを俺の頭の中に叩き込んできた・・・。
怖いからお前にやる。
extern struct zyx {} const zyx;
struct float3{ float x, y, z;
float3 operator ->* (struct zyx const&) { float3 zyx = {z, y, x}; return zyx; }
};
float3 v0;
float3 v1 = v0->*zyx;
>>485 プロパティな動作をさせたいってことか。C++永遠のテーマですね。面倒だけど困ったときのプロキシークラスを使えば無いことも無い。
class YZ
{
double y;
double z;
public:
YZ(double y0,double z0):y(y0),z(z0){}
};
class XYZ
{
double x;
double y;
double z;
class yz_prop
{
XYZ* a;
public:
yz_prop(XYZ* a0):a(a0){}
operator YZ(){return YZ(a->y,a->z);}
};
public:
XYZ(double x0,double y0,double z0):x(x0),y(y0),z(z0),yz(this){}
yz_prop yz;
};
int _tmain(int argc, _TCHAR* argv[])
{
XYZ v0(1,2,3);
XYZ v1=v0;
YZ v2=v0.yz;
return 0;
}
そんでxzyとかzyxとかの全パターン生成にはboost::preprocessorを使うな。
>>485 ベクトル演算(回転と写像)に見えた。
であれば、自分ならそういう風にオブジェクトを構築するかなぁ。
Y^´ ∨// /,∠ ,. ' /l/// /, ' , '/ ! | l }´ 〈 〉 変 〈/ , ' // ̄`>< /// /// _,.=‐|'"´l l〈 変 / 〈 態. ∨, '/l| ,.'-‐、`//`7/ /''"´__ | ハ l丿 態 { 人) ! ! (/! |ヽ〈_ ・.ノ〃 〃 / '/⌒ヾ.! ,' !く ! ! (_ ト、__/ ヽ、_,.イ /l l |:::::::```/:::::/...´.. //´。ヽ }! ,' !! ) / ト' 亦 ,イ⌒ヽ/ !l l ! l し J ::::::::::::::::::::``‐-</ / ,'、`Y´Τ`Y l 夂 (ハ ヽ l i ! l ', ! , -―-、_ ′::::::::::::: //! Λ ヽ、ヽl ヽ 〉,\ ! i ',.l `、'、/_,. ―- 、_``ヽ、 ι 〃,'/! ヽ、\ ヽ、 ! 能 // ,' lヽ! ii ',l ∨\'⌒ヽー-、 `ヽ、! / ハ ノヽ._人_从_,. \ | 心 { / ,' ' ,! ll l`、 { ヽ' \ ヽ ' '´ Λ ',} ( \ .丿 ∨ // ,',! l l l ヽ`、 \ \ ∨ し /! ∨ 変 ,ゝ、 ∧ / / ヾノ //l l l l、_ヽ\ \ ヽ , ' ,.イ |ノ 態 (ヽ /ノ__ ゚ ゚ (⌒`〃'j | l l l `ヽ `ヽ、.ヽ _,.}'′ ,.イl { | ヽ ! ! ,ゝ\ / /`Y⌒ヽ/⌒ 〃 ノ | l l l } ヽ、._ } ノ,.イ l | ! ! | )_
>>490 ベクトルには違いないが単にシェーダーで使えるswizzlingをやりたいだけだろ
>>485 本当に処理系依存でいいのなら__declspec(property)を使うというのはどうだ。俺は使った事は無いが。
まぁ、やり方はすぐ思いつくが、もりもり不幸な予感がするのも間違いないw
template<class T, class U, T (U::*F)(void)> class ReadProperty { public: ReadProperty() : pT_(0) {} void operator(T* pT){pT_ = pT;} operator U () const{return (pT_->*F)();} private: T* pT_; }; class XYZ { YZ getYZ(){return YZ(y_, z_);} public: XYZ(z,y,z):x_(x),y_(y),z_(z){yz(this);} ReadProperty<XYZ, YZ, &XYZ::YZ> yz; private: float z_, y_, z_; };
>>485 #include <iostream>
using namespace std;
void main(){
struct float3{ float x, y, z;};
struct float2{ float y, z;};
float3 v0 ={ 1 , 2 , 3,};
float3 v1 = v0;
float2 v2 = *((struct float2 *)&v0.y);
cout<<"v1x "<<v1.x <<endl;
cout<<"v1y "<<v1.y <<endl;
cout<<"v1z "<<v1.z <<endl;
cout<<"v2y "<<v2.y <<endl;
cout<<"v2z "<<v2.z <<endl;
}
まぁ多分うごく
規約には&v0.yのアドレスの次に&v0.zを置きましょうなんて無いと思うけど
たった4バイトだからそうそうズレやしないかと
>>496 そのキャストは危険。派生させればキャストは不要。
class float2
{
float x;
float y;
};
class float3 :public float2
{
float z;
};
float3 v0;
float3 v1=v0;
float2 v2=v0;
コピーの話はしてねぇから
499 :
デフォルトの名無しさん :2009/09/19(土) 19:19:41
キャレット位置の取得の仕方について質問させて下さい。 使用しているエディタ(メモ帳、サクラエディタ等)のキャレットの位置に ポップアップメニューを表示させたいのですが、 キャレット位置の取得の仕方が分かりません。 GetCaretPosという関数がそれに近いようなことをできるのかと思いましたが、 使ってみると、ポップアップメニューが毎回、画面左上に表示されます。 // キャレット位置 POINT pt; //キャレット位置取得 GetCaretPos(&pt); 環境は VC++2008 Express Editionです。 どのようにすればよいでしょうか。 よろしくお願いします。
>>499 まずは MSDN を見て、戻り値を見て、まだ何かあれば Windows API スレへどうぞ。
struct float3{ float x,y,z; struct zyx_{ float& x; float& y; float& z; zyx_(float& x,float& y,float& z):x(x),y(y),z(z){} }zyx; float3():zyx(x,y,z){} float3(float x_,float y_,float z_):zyx(x,y,z),x(x_),y(y_),z(z_){} float3(const zyx_& a):zyx(x,y,z),x(a.z),y(a.y),z(a.x){} }; int main(){ float3 v0(1,2,3); float3 v1 = v0.zyx; std::printf("%f,%f,%f\n",v0.x,v0.y,v0.z); std::printf("%f,%f,%f\n",v1.x,v1.y,v1.z); return 0; }
>>502 のzyx_クラスのメンバはprivateで
504 :
デフォルトの名無しさん :2009/09/19(土) 20:39:29
>>500 分かりました。
そちらで聞いてみます。
マクロでもテンプレートメタプログラミングでも良いから、 ある識別子(?)が何回記述されているかをコンパイル時に取得する方法はない? 例えば #define M_A_C_R_O() *** int main() { char array[M_A_C_R_O()が出現した回数]; M_A_C_R_O() M_A_C_R_O() return 0; } という様なコードが通り、 コンパイル時に char array[2]; となるようなもの。
506 :
505 :2009/09/19(土) 20:54:21
#define M_A_C_R_O() *** int main() { M_A_C_R_O() char array[M_A_C_R_O()が出現した回数]; M_A_C_R_O() M_A_C_R_O() M_A_C_R_O() return 0; M_A_C_R_O() } これだったらchar array[5]になるってことで。
多分不可能
T array[] = { Macro(), Macro(), ... Macro(), }; // 必要ならば // #define arraysize (sizeof(array)/sizeof(array[0])) では何が足りないのか知りたい。
509 :
505 :2009/09/19(土) 21:34:15
>>507 ですかねぇ。。。
今のところ、
template <unsigned int linenum>
hoge{〜〜〜〜};
#define M_A_C_R_O() sizeof( hoge< __LINE__ > )
として、
int main()
{
M_A_C_R_O();
M_A_C_R_O();
M_A_C_R_O();
return 0;
M_A_C_R_O();
}
こんな感じでどうにか出来ないかと思っているんだが。
510 :
485 :2009/09/19(土) 22:29:35
いろいろなお答えありがとうございます。
出来ないと思って、駄目もとで聞いてみたんですが
C++標準で出来るんですね。凄いですね。
確認した結果、
>>493 のMS拡張が最も楽そうですので
まずはこちらから試してみたいと思います。
大変ありがとうございました。
>>487 さんの変態コードの意味がどうしても分かりません。
特に
> extern struct zyx {} const zyx;
が何を意味したいのがが分かりません。
どなたかご教示ください。
よろしくお願いいたします。
>>509 テンプレートが実体化されたかどうかの情報は内部から得られない
そしてマクロは自分が展開される所から先の情報を得ることはできない
なので無理と判断した
>>511 float3 operator ->* (struct zyx const&) で演算子を選択させるための識別子を作ってるんじゃないか?
識別子を増やして、演算子のオーバーロードを増やせばいろいろできるね。
>>513 あーなるほど。
最適化で消えるっていうアレですか。
ありがとうございます。
>>510 やりたいことがうまく伝わってない人もいっぱいいるように見えるけどね
zyxだけじゃなくて、yxzとかyzxとかはいらないの?
>>509 boost::preprocessorのBOOST_PP_SLOTを使えば個数は取得できる
ただし#includeを使ってカウントする都合上__LINE__は取得できない
連番のヘッダファイルを用意して__FILE__を代用に使うという方法を試してみたが正直これはダサい
まあ一応貼ってみる
// ./counter/99 (0〜99まで100個用意:対象cppの行数分だけ)
#ifndef COUNTER_99_
#define COUNTER_99_
{ static int flag=0;
if(!flag){ std::cout << __FILE__ << std::endl; flag=1; } } //__FILE__に行数が入っている寸法
# define BOOST_PP_VALUE BOOST_PP_SLOT(1) + 1
# include BOOST_PP_ASSIGN_SLOT(1)
#endif
// main.cpp
#include <iostream>
#include <boost/preprocessor.hpp>
#define BOOST_PP_VALUE 0
#include BOOST_PP_ASSIGN_SLOT(1)
#define CURRENTLINE BOOST_PP_CAT(counter/,__LINE__) //行番号に対応するファイルをインクルード
#define M_A_C_R_O() BOOST_PP_STRINGIZE(CURRENTLINE)
#define M_A_C_R_O_C_O_U_N_T BOOST_PP_SLOT(1)
extern const int count;
int main() {
#include M_A_C_R_O() // .../counter/11
#include M_A_C_R_O() // .../counter/12
std::cout << count << std::endl; //3
return 0;
#include M_A_C_R_O()
}
static const int count = M_A_C_R_O_C_O_U_N_T;
>>510 C++ならプロパティにこだわらずゲッター関数を使うことをお勧めするぞ。手間は変わらない。
プロパティとかインデクサっぽいことはできるけど めんどくさいしちょっとコスト増えるから type name(size_t index0, ...) const; void name(size_t index0, ..., type val); あるいは const type& name(size_t index0, ...) const; type& name(size_t index0, ...); これで妥協しちゃうなぁ
520 :
505 :2009/09/20(日) 12:13:55
>>516 ありがとうございます。
すげぇ。
ご教示の通りに
ttp://uproda.2ch-library.com/lib170991.zip.shtml を作って動作させてみました。
VC++で問題無く動作することは確認いたしましたが、
g++ (TDM-1 mingw32) 4.4.1では
main.cpp:12:1: error: pasting "/" and "12" does not give a valid preprocessing token
main.cpp:13:1: error: pasting "/" and "13" does not give a valid preprocessing token
main.cpp:16:1: error: pasting "/" and "16" does not give a valid preprocessing token
main.cpp:18: error: 'count' was declared 'extern' and later 'static'
main.cpp:10: error: previous declaration of 'count'
というエラーメッセージがでてコンパイルできません。
VC++とg++両方でコンパイルが通るようにするにはどうしたらよいでしょうか?
よろしくお願い申し上げます。
>>520 516じゃないけど、多分これでいける
× #define CURRENTLINE BOOST_PP_CAT(counter/,__LINE__)
○ #define CURRENTLINE counter/__LINE__
523 :
505 :2009/09/20(日) 15:45:53
>>522 ありがとうございます。
それでかなりコンパイル成功まで近づきました。
しかしまだ
main.cpp:18: error: 'count' was declared 'extern' and later 'static'
main.cpp:10: error: previous declaration of 'count'
というエラーが出てしまいます。
どうしたものでしょう。。。
524 :
516 :2009/09/20(日) 16:29:11
>>523 悪い。VCでしか確認してなかった。
18行目のstaticを削ってみておくれ。
>>522 フォローthx
525 :
505 :2009/09/20(日) 23:11:10
526 :
505 :2009/09/20(日) 23:22:45
と、気付いたのですが、これだとコンパイル時定数にはならないようです。 現在のところコンパイル時定数でなくても困っていないのですが、 将来的にはコンパイル時定数に出来ないかどうか頑張ってみます。
527 :
505 :2009/09/20(日) 23:46:49
自分でも
ttp://codepad.org/IhxI58eT テンプレートメタプログラミングで階乗を求める方法をまねして
みたのですが、やはりダメでした。
// M_A_C_R_O();
をコメント解除するとエラーになります。
これは1パスでプリプロセス処理やコンパイル処理が行われる関係上、
当然な話なのですが、やはり無理でした。
>>525 のソースが一番良さそうです。
何も全部C++でやらんでビルド前にgrepとかで数を調べて ヘッダにでも書いておけばいいんじゃねーかとも思う
529 :
505 :2009/09/21(月) 07:02:27
>>528 おっしゃるとおりです。
極論すれば
「興味のため」に「それすら自動化したい」
といった理由です。
さて、俺様が子一時間はまった宿題を出してやろう、このプログラムには致命的な間違いがある、どーこだ もまいらは頭が良いから、直ぐにわかると思うが。 // CPoint.h template <class T> class CPoint { template<class> friend class CPoint; private: T x_; T y_; public: // Constructor CPoint(T x = T(), T y = T()) : x_(x), y_(y) {} CPoint(const CPoint& pt) : x_(pt.x_), y_(pt.y_) {} // Operator overload CPoint& operator+=( const CPoint& pt ) { this->x_ += pt.x_; this->y_ += pt.y_; return *this; }; CPoint& operator+( const CPoint& pt ) { CPoint q(this->x_ + pt.x_, this->y_ + pt.y_); return q; }; template <class U> CPoint(const CPoint<U>& r) : x_(r.x_), y_(r.y_) {} };
コンパイルのコマンドがclとしよう。 clの前に、単語を数えるexeを動かすBATファイル作れよ。
>>529 >>528 が言ってるのはビルドプロセスの中で
hoge.cpp
int main()
{
char array[
#include "hoge_count.h"
];
M_A_C_R_O()
M_A_C_R_O()
}
grep --count '^ *M_A_C_R_O()' hoge.cpp>hoge_count.h
みたいにしろってことじゃない?
だから自動化は出来るよ。
コメントとか文字列リテラルとかプリプロセッサ命令とかのことを考えるとアレだけど。
あとは、自分でプリプロセッサを作るとか。
533 :
531 :2009/09/21(月) 10:07:01
いちど、defineやメタプログラムなどを展開する必要があるな。 一度、展開してやつを数えるBATファイル作れよ。
マクロ展開したらマクロ数えられないじゃんw
マクロが動くときに動きそうな、何かの関数ポインタが参照された回数を数えればよろし
UltraMiracleSpecialThunderSuperKnuckle{
};
>>536 これで満足か?
>>530 > CPoint& operator+( const CPoint& pt )
> {
> CPoint q(this->x_ + pt.x_, this->y_ + pt.y_);
> return q;
> };
ナニコレ
>>538 >>530 です、
流石2ちゃんねる、お前年収1000万以上だろ、素晴らしいね(・∀・)ニパ、正解です。
ま、俺は三億ベリーだけどな
そういやおまいら、>530見てて思ったんだけど、 > CPoint(T x = T(), T y = T()) : x_(x), y_(y) {} みたいなデフォルトコンストラクタってどうよ? なんか効率悪そうなんでわざわざ3つ用意するようにしているんだけど、どうなのかね? CPoint(T x, T y) : x_(x), y_(y) {} CPoint(T x) : x_(x), y_() {} CPoint() : x_(), y_() {}
CPoint(T x)は気持ち悪いから俺なら作らない 作るとしてもexplicitを付けるべきだ
>>542 効率はともかく、
>>530 のそれは、自分の中で「引数の省略」というのを使うべき時
の条件に何となく合致しない感覚があるから、俺は素直に分けて書くな
あと
>>544 にも同意
>542 アセンブラのソース見れば効率いいかどうかわかるが 気にするだけ無駄
> 気にするだけ無駄 だな。 引数がコンパイル時定数で最適化しつつinline展開するならほぼ同じバイナリになるほうが自然だろうよ。
548 :
505 :2009/09/21(月) 14:19:12
>>532 あーなるほど、そう言う意味ですか。
確かにそれなら自動化できますね。
>>535 面白そうですね。
すみませんがどういう実装をすれば実現できますでしょうか?
識別子を数えたいって…おまえさんLisp経験者?
550 :
505 :2009/09/21(月) 22:45:05
>>549 いいえ、あんなに高度な言語は分かるように努力する気がしません。。。
ただの趣味グラマでございます。
そのため
>>529 の様な、本職の方々からすればのんきなことを申しております。
>>550 趣味プログラマでそのレベルまで出来るもんなんだね。
俺は
趣味プログラマ=Hello Worldに毛の生えたようなもの
だとしか思ってなかったわ。
それはねーわw つい最近趣味グラマから転職で本職にはなったけど C++とQtで一通りGUIは扱えるし、Linux鯖云々も扱える WinAPIは手を出したけど気持ち悪さから手を引いた Cオンリーの超閉鎖的な組込みに入ったから、 持ってるもののほとんどはニアミスすらしないけど
趣味上がりの人の方が知識は豊富なことが多いかも。 それで天狗になって業務の基礎知識を得ようとしない人も結構いるから、そうならなければ大事な戦力。
>>552 そうでも、C++ を使い込んでいれば、Cで組んでも発想の引き出しが多いと思うよ。
あと、Linux でスクリプトとかも使ってれば QA のテストとかにも便利だし。
>>553 うん、気をつけるよ
もともと一番弱い部分(HW)を得るためにってのもあって、
組込みに行ったんだし
その辺のバランスは難しいんだよね 自分に無い能力を素直に認めて吸収するならどうにでも伸びるんだけど、例えば C++で高度に抽象化したコードを見ると「現場の役には立たねぇ」とか逃げる奴も いれば、逆に敢えてプリミティブに書かれたコードを見て「抽象化を進めないと 話にならない」と思いこむ奴もいて、そういうのはどっちも問題があるなぁとか
ところで、Hello Worldに毛の生えたレベルの人は採用試験で落ちるような気がするのだが。
それがそうでもないんだな・・・ 原発で潤ってる某財閥の冠しょってる子会社に ただ、情報系卒ってだけで採用された 職業訓練校通ってた同期で、 変数の宣言すら知らなかった もちろんprintfなんて扱えるわけもなく つーか、隣の人の丸写しすらできないほど
人としての価値があったんだろ
>>558 の思いも拠らない部分で
そのために研修があるんじゃないの
Cは3ヶ月でマスターできるけど C++は3ヶ月でマスターするにはかなり一生懸命勉強する必要があるぞ。
>>561 マスターってどのくらいの程度を言うのか知らんが・・・
> ○○言語で○○らしいプログラミングができる
を目標とするならそのくらいだろうな。
マスターできない人はSEとして、マスターできた人はPGとして働く そういう会社がすごく沢山あるよね
exportは忘れるとして、それ以外でもC++の標準規格を100%完全に満足する実装は未だ存在していないと聞いたんだが。 Comeauが完全サポートに一番近いんだろうけど。 そんな中、C++0xの規格をさらに定めたりしているんだが、 本当に理論上可能で矛盾がない規格であることは確かめられているの? つまり理論上は実現可能であることは分かっているものなの? (例:テンプレートメタプログラミングはチューリング完全である よってチューリング機械が実現できることは 何だろうと(理論上は)テンプレートメタプログラミングでも出来る)
>>564 こういう人って論文の査読が通っても信じなさそう。
統合失調症?
C++ なんて所詮現実主義で実用主義。
>>564 みたいな人は Lisp とかの方が良いと思う。
>>564 矛盾があってもなにか実害が?
間違いは直せばいい。
>>564 はLispも実用主義すぎてだめだろ。たぶんHaskellが最適。
569 :
564 :2009/09/22(火) 14:42:04
ああいや、そうじゃないんだよ。 俺はC++大好きなんだが、 勝手にC++標準化委員会がC++0xで規格を追加したりして、 コンパイラベンダーは大変だなあと言いたかっただけだ。 本当に実現可能な規格じゃなかった(つまり内部に矛盾がある規格)としたら コンパイラベンダーの標準準拠にかける努力はどうしてくれるのかと。
570 :
564 :2009/09/22(火) 14:43:37
>>565 ごめん何が言いたいのかわからん。
無視していい?
>>567 > 矛盾があってもなにか実害が?
そりゃさすがに実害ありまくりだろw
> 間違いは直せばいい。
ここは賛成。
標準化委員会にはMSやGNUやインテルの中の人たちも参加してるぞ
>>571 じゃあ彼らも覚悟の上で仕様を決めているということか。
コンパイラ作る人ってすげーなー
まぁC++コンパイラを作るような人達は、いい意味でキチガイ限定だからな 常人がC++コンパイラを作ろうとすると、あまりの泥沼ぶりにC++の粘着批判を始めて うざい人になったりする
メモ代わり。 VC++2003。#includeするヘッダファイルと ソリューションエクスプローラーで追加してやるヘッダファイルが違ってた。 それぞれのヘッダファイルはほぼ同じ内容。片方がテンプレ的存在。 それに気づかないままコンパイルするも プログラム終了時にafter normal block(#47)を吐く。 ヘッダファイルに書かれたクラスをnewするとエラーを吐いて newしなかったらエラーを吐かないという意味不明なエラー。 deleteしてもしなくても関係ないし、名前空間の問題でもなさそう。 ポインタ回りかと思って"64ビットへの対応"をきったらエラーを吐かなくなった。 最終的には上述の理由に気づいて正しくコーディングできたが なんかよく分からんエラーが出たなぁ。
お前の文章力がないのはわかったからチラシの裏に書け
本気でイミフでワロタ
スレ違いのチラ裏をメモとか頭おかしい
C++文法全部投げ捨てて一から作り直したほうがいいんじゃないかって素人の俺は思う。互換性なんかしるかァァァァァ
この弱虫ッ
分からないまま批判するのはみっともないからやめとけ
一から言語を設計したら他人のコードを借用しずらいから。
>>578 互換部分なんか使わなくなるよ。
ポインタなんかスマートポインタにパックしてしまえばまったく気にならなくなるし。リーク?なにそれ?
STLを使えば配列?なにそれ?状態だし。
参照使えば0オーバーヘッドで且つ安全だし。
C#最高 速度? そんなもん、すぐに解決だろw かつてはCでさえ遅かった。
585 :
デフォルトの名無しさん :2009/09/22(火) 20:53:29
boost::filesystem以外で クロスプラットフォームな ファイルシステムライブラリはありませんか? opendirを使いたいのですが、日本語(UNICODE)対応で 困っています。 boost::filesystemは使い方が大きく変わってしまうので、 opendirと似たインターフェースがいいなぁ。
クロスプラットフォームGUIフレームワークのライブラリQtやwxWidgetsにはファイル関係のライブラリが含まれてたよ。
>>586 レスありがとうございます。
ただ、ファイル扱うだけに、GUIフレームワークとは
ちょっと大きすぎますね・・・。
(簡単に)部分取りできるのだろうか?
できれば、ファイルシステム関係のみの
ライブラリがあるといいんですが。
(現在ちょこちょこ作っていたりはする)
>>585 apr どうよ? C++ じゃなくて C だったような気がするけど。
おぉ aprがありましたね。 ざっと見たところ、opendirと似ているような、似ていないような? これって文字コードは何で指定/取得するのだろう? たとえばfopen相当の関数で開くときのパスとか、 readdir相当の関数で取得されるパスとか、 全部UTF-8で統一されているのかな?だといいなぁ。
C#使うぐらいならJavaでイナフ
>>583 互換部分は俺は結構使うな。既存のライブラリとインタフェースするから。
よく使う時は wrapper 的に書くけど。既存のライブラリを使えるのがC++ の強み。
あと、互換部分は基本的に使わないけど I/O だけ使う(printf,scanf)という
人もよく見る。C に慣れてる人にはしっかりフォーマットするには楽だからね。
printfを使ってコンソールに♥を出力してみろってンだ。
>>593 std::coutでそれを出力しろって言ってるのと変わらんだろう。
最近GUIばっか触らせられてて標準入出力と無縁なのでboost::formatだけの生活
ほんと C++/GUI 生活になると、ちょっと計算するだけのテストexe作るのにすごい手間がかかってしまう
>>597 計算だけなら GUI 無しとかスクリプトで組むとかなら楽では。
599 :
デフォルトの名無しさん :2009/09/23(水) 01:15:05
まじキチ…ユダヤが人工地震を起こすぞ
【緊急情報カクサンよろしく】
ついに来ました。
大きい動きです。250nT超えてきました。ほぼ間違いありません。もう一度言います。
友人、知人、親類縁者、あらゆるつながりを駆使して巨大地震がくることを教えて下さい。
四川地震より大きいのが来る可能性があります。
http://g ★olde★ntam★atama.b★lo★g84.fc2.c★om/
★★★★★危険度MAX★★★★★
★★★★★★★★★★★★★★★★
★千葉、静岡、東京、関東で大地震が起きる可能性が非常に高くなっています★★★
★千葉、静岡、東京、関東で大地震が起きる可能性が非常に高くなっています★★★
★千葉、静岡、東京、関東で大地震が起きる可能性が非常に高くなっています★★★
★千葉、静岡、東京、関東で大地震が起きる可能性が非常に高くなっています★★★
★★★★★★★★★★★★★★★★
★★★★★危険度MAX★★★★★
警告!連休中の21、22、23日が危ない!かも2
http://live24.2ch.net/test/read.cgi/eq/1 ★253494015/
【大気イオン】e-PISCO Part11【また延長】
http://live24.2ch.net/test/read.cgi/eq/1 ★252991726/
本当に地震が来たら、犯人は特権階級全員だということ2
各ベンダの独自機能を使えばそれっぽい事はできる。
>>601 やっぱり処理系依存ですか。
ありがとうございます。
>>602 処理系依存ではないでしょ。
独自機能を使えばできるって言ってるだけ。
#define TEMP 1
#define MYVAL TEMP+1
#undef TEMP
#define RET MYVAL
RET は MYVAL に展開されて、MYVAL は TEMP + 1 に展開されるが、
この時の、TEMPはundefしちゃってるからエラーってところかな。
604 :
602 :2009/09/23(水) 11:51:17
>>603 ありがとうございます。
ええと、
> 処理系依存
でない
> 独自機能
とは、どういった意味でしょうか?
仕様に入ってない機能ってことだろ
仕様ていうか規格。
>やっぱり処理系依存ですか。 処理系に依存しないと出来ないのですか。 じゃないの?
何を言ってるんだ
609 :
602 :2009/09/23(水) 14:52:59
ああ、すみません。 理解致しました。
そんなことができる処理系独自の機能について知りたい。 コンパイラの名前とその機能の使用例を教えみて。
1と2だけおk
>>612 そうだったんですか。
ありがとうございます。
初めて知りました。。。
>>611 The C++ Standards Committee の 現在のドラフト
ttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf の16章(450-451ページ)によると
A preprocessing directive consists of a sequence of preprocessing tokens. that satisfies the following constraints:
The first token in the sequence is a # preprocessing token that (at the start of translation phase 4) is either
the first character in the source file (optionally after white space containing no new-line characters) or that
follows white space containing at least one new-line character.
The only white-space characters that shall appear between preprocessing tokens within a preprocessing
directive (from just after the introducing # preprocessing token through just before the terminating new-line
character) are space and horizontal-tab.
とある。全部OKなような気もするが。。
615 :
612 :2009/09/23(水) 17:05:39
私も仕様書を読んでみたところ、
全部OKに思えてきました。
Boostでもそうなっているあたり、
やはりどれもOKなのでしょうね。
>>614 ありがとうございます。
617 :
615 :2009/09/23(水) 17:11:39
すみません私は
>>612 氏ではなく
>>611 でございます。
ミスです。お詫び申し上げます。
>>616 ありがとうございます。
私も該当箇所を読んできました。
例外を投げるときは、オブジェクトの状態を元に戻すって教わったのですが C言語の FILE をラップしたようなクラスで fclose がエラーを返した場合、例外を投げるとすると もう一度クローズ処理が出来る用にしないといけないのでしょうか? その場合、C言語の fclose は1度目の呼び出しで失敗した場合も エラーを返してファイルをクローズしてしまうため、再びクローズを試みることが 出来ないのだけど、どうすればいいんでしょうか?
>>618 「再びクローズ」ができないとわかっているなら、最初の質問が意味無いね。
基本保証しか提供できないってことじゃ炉。
fcloseが失敗した時点でアプリができる事はないのでキニシナイ
ちゃんとユーザーにエラー通知しろよw ちゃんとファイルを書き込めてると思ってアプリを終了したら、後でユーザーが泣くぞ。 エラー通知されてればユーザーには別のファイルに保存するとかそういう選択も可能になるんだから。
>>618 > 例外を投げるときは、オブジェクトの状態を元に戻すって教わったのですが
この一行目から既に意味が曖昧すぐる
いや、だから、「例外」というエラー通知をしてるだろw 例外を発生しないなら戻り値による成否の通知が必要だが ここは例外発生が前提だから。
#include <utility> #include <iterator> #include <iostream> template <class Left, class Right> std::ostream& operator << (std::ostream& out, const std::pair<Left, Right>& pair) { return out << pair.first << ' ' << pair.second; } int main(void) { using namespace std; cout << make_pair(10, 20) << endl; // ok ostream_iterator<pair<int, int> > it(cout, "\n"); *it = make_pair(100, 200); // ng *it = make_pair(300, 400); // ng *it = make_pair(500, 600); // ng return 0; } なぜイテレーターのほうがエラーになるのでしょうか?
ミス。無視してくれ
クラス型のstaticなメンバ変数を使う場合ですけど、そのクラスの コンストラクタから例外がでたときはキャッチすることができないん ですよね。 皆さんどうしてますか? staticメンバには組み込み型か、自作クラスでコンストラクタがthrow() なものしか使わないとか。
エラーが起きるようなものは明示的に初期化してます
>コンストラクタから例外がでたときはキャッチすることができないんですよね。 それは都市伝説だ
>>618 オブジェクトの状態を元に戻すってのは
例外投げるなら、結果的に何もしなかった状態になってろってってことであって、
再びfcloseで閉じられる様にするってのはちょっとズレてる。
ファイルの例なら、例外が発生しても開いたファイルは何も変更されて無い状態を保証する。
で、そんな保証が出来るとは限らないから
そういうときは、変更しようとしてるデータが生きてることまでは保証して
>>623 の言うような、なんかエラー通知して、他の手段を提供するとか。
まあEffective C++嫁
>>629 別に、なんとも。実際に例外が発生すると terminate() するんだけど、当然だと思うし。
例外投げない保証があるオブジェクトじゃなくても、ヒープからメモリ確保する奴も
プログラム起動時に走るんなら問題ないだろうね。
>>631 > クラス型のstaticなメンバ変数を使う場合ですけど、そのクラスの
この条件なら正しいだろ。
>>630 それが妥当ですかね。私もそれを採用してます。
>>631 staticメンバだってとこ見落としてる?
>>633 terminate()は避けたいですわ。
例外はアプリで全てキャッチしたい。
636 :
633 :2009/09/25(金) 10:00:32
>>635 terminate() を避けたいなら、実際に例外が発生しないようにすればいいわけで、
>629 みたいに型の段階で絞る必要はないってこと。
プログラム起動時なんだから、たとえば bad_alloc が出るかどうかなら一回試せば
結果はすぐわかるし、ファイルの有無とか外部要因によって例外が出たり出なかったり
するんなら >630 だろうし。
637 :
633 :2009/09/25(金) 10:09:32
> プログラム起動時なんだから、たとえば bad_alloc が出るかどうかなら一回試せば ごめん。これは環境に依存するね。 OS 無しのスタンドアロンでヒープサイズ固定な環境でしか通用しない話だった。
>>487 のコード見てたら、こんなん思いついた。
struct float3{ float x, y, z;
float member(char c) const { switch (c) { case 'x': return x; case 'y': return y; case 'z': return z; } }
float3 operator ->* (char const (&order)[3+1]) const { float3 const result = {member(order[0]), member(order[1]), member(order[2])}; return result; }
};
float3 v0;
float3 v1 = v0->*"zyx";
float3 v2 = v0->*"xzy";
float3 v3 = v0->*"yxz";
operator ->* に、何かすごい可能性を感じた。
たぶん気のせいなんだろうけど。
静的記憶に置くクラスを作る時は、コンストラクタは例外投げないように書いて、 init()で初期化してるなぁ。 つーかinit()で初期化するのって結構よく使われてるよね。Googleとかもそうじゃ なかったっけ。GoogleのC++コーディング規約あんまり好きじゃないけど。
>>639 > つーかinit()で初期化するのって結構よく使われてるよね。
めんどくさいから、そんなことしないほうがいいだろ。
そんなの付いてるのは古いクラスライブラリだけだよ。
めんどくさいけどそうしなきゃならない時があるんだよ
何のためのコンストラクタなんだ。
コンストラクタも基本的な初期化で使う 初期化コードは必ず全部をコンストラクタに突っ込まなきゃいけない、という話じゃない ってだけ つーか静的領域とコンストラクタに関連する問題を理解してるんだろうか
ユーティリティ関数としてprivateにinit()を用意することは良くやるけど それをpublicに置いて自由にアクセスできるようにするのはあんまりやらんなぁ。
じゃどうやって静的記憶に置くクラスの初期化の失敗を処理するんだ? 勝手にterminate()していいよ、なんてのは論外として。
646 :
642 :2009/09/25(金) 12:08:58
>>645 まあ確かにどうしても初期化に失敗する可能性のあるクラスを
かかなきゃいけないことはあるしなぁ。
コンストラクタから例外を投げたいところだが
静的記憶に置きたいならもうどうしようって感じだよね。
>>645 ポインタ置いといて new とか、ローカルな static インスタンスへの参照を返す関数とか。
そもそも静的記憶に置くこと自体が一般的にはマイナーな使い方だし、こういった
回避方法もあるので、それだけで二段階初期化の根拠になるような問題ではない。
少なくとも、二段階初期化はやむをえない事情がある場合に限って使うべきもので
あって、変な理屈で「よく使われている」なんて話にされると迷惑。
>>647 Googleとは真逆の意見すね。
まぁ、どっちが優れてるかは分からんけど。
>>648 compressed_pairさんが採用されてるw
>>648-649 Google のやつは前提として例外を禁止しているからそうなってるんだよ。
例外が使える環境で Google のそれに倣う必要はない。
シングルトンの問題も仲間に入れてと思い書きます。 スレッドセーフにする為にstaticなmutexを置いたりする必要がありますよね。 mutexのコンストラクタが例外出さないなんて保障あんのかよと思いつつ面倒なんで黙って置いたりしてます。 これに触れてくれているの見たことないんですけど、どんなもんでしょうか? まあ、mutexのコンストラクタで例外なんて99.9999%ないんですけどね。
静的記憶は例外が使えない環境だよな
>>652 シングルトンは正直、余計な面倒が多すぎてアンチパターンになりつつあるような。
Google式に初期化を分離してグローバルインスタンスにでもした方が綺麗に収まると思う。
どっちのやり方でもやっていけるんなら、あとは質問者が選べばいい問題なんじゃね?
これ以上続けても宗教論争になるだけだし。
というか
>>635 で既に質問者の選択はされてるし。
>>626 operator<<をstd名前空間に入れる。
stdにある既存のoperator<<にglobalなoperator<<が隠される、というのが理由らしい。
規格的には知らん。
>>657 おっとそいつは undefined behavior だぜ。
>>657 std名前空間にはいかなる物も追加してはならない。
ただテンプレートの完全な特殊化のみ例外的に認められている。
・・・っと、あれ?クラステンプレートの部分特殊化もOKだっけか?
(関数テンプレートの部分特殊化はC++自体が当然不可能として。)
C++の名前空間は最初は便利なものだと思ってたけどだんだん嫌がらせに思えてきた どうにかしてほしい
>>659 確かに
C++98 標準では、ユーザ定義型に対しては std::swap の
完全特殊化のみ std 名前空間に定義することを認めている。
部分特殊化や、関数オーバーロードは認められていない。
だそうだけど、 std 名前空間におけるクラステンプレートは
部分特殊化もOKだったと思う。
うん、何となく。
詳しくは有識者を待とう。
επιστημη…
名前空間はなんか気持ち悪いから積極的に使おうとは思わん stdは使いまくってるけど^p^
^p^←こいつは偽者だと言っとるだろうがまだ分からんのかあああああああああああああああああああああ
668 :
デフォルトの名無しさん :2009/09/25(金) 19:25:52
>>661 俺がいまやってるプロジェクトでは名前空間名だけで30文字
以上になるような規約を押し付けられてる。
テンプレートをネストさせたりするともう基地外状態。
>>622 何のエラーも吐かず通るBCCが気持ち悪い・・・
>>648 RTTIが禁止ってポリモーフィズムを使わないってこと?
なんか汎用性が低そうなモノが出来そうな気がするんだけど。
typeidとdynamic_castが禁止なだけだろ
「C++ template metaprogramming」と「C++ templates」はどっちが読み易い英語ですか? (主観でいいです)
両方変わらんよ。 両方読め。
>>671 明示的には書かないけど、アップキャストもdynamic_castじゃないの?
>二段階初期化 初期化時に自分のポインタをよそに渡したいというときがあるけど、 構築が完了するまでそのポインタは使い物にならないから 構築が完了したあとに初期化関数でポインタをよそに渡すという仕組みにすることはある 特に別スレッドにポインタが漏れる恐れがあるときはちゃんとやらないと死ねる
相手に自分のポインタを渡すってのはろくなことにならないことが多い 相互に参照しあう関係って非常にだるい
>>677 それはあんたの設計がヘタクソなだけだろう。
>相互に参照しあう関係って非常にだるい 「参照」を「依存」に置き換えるとなんだか意味深♪
>678 のが下手糞に思える俺は駄目ですか?
>>648 コンストラクタのコーディングスタイルのところは、昔の自分を見ているようだ。
昔はデフォルトコンストラクタ、デフォルトコピーコンストラクタ、デフォルト代入演算子が
副作用起こしまくりで閉口したもんだ。
でも今はRAIIを徹底してデフォルト〜を期待して書いている。
早い話がデフォルトコンストラクタを持つクラスのみをメンバ変数にすればデフォルトコンストラクタが自動生成されるし、
デフォルトコンストラクタを持たないクラスをメンバ変数にすればデフォルトコンストラクタが作成できなくなる。
他のデフォルト〜も同様だね。
例えばコピーできないファイルハンドルはboost::nocopyableをつけてクラス化したメンバ変数を作っておけばコンパイラがデフォルトコピーコンストラクタをエラーにしてくれる。
共有できるポインタはboost::shared_ptrでメンバ変数を作ればコンパイラがデフォルトコピーコンストラクタを作ってくれるし、
共有できないポインタはboost::scoped_ptrでメンバ変数を作ればコンパイラがデフォルトコピーコンストラクタをエラーにしてくれる。
デフォルト〜を利用しようぜ。
>>675 アップキャストはRAII使わないよ。static_castの範疇。
デフォールドでヤックデカルチャーです。
>>675 アップキャストはコンパイル時に絶対安全と保証される暗黙的型キャスト。RTTIは不要。
暗黙的型キャストに限定されたboost::implicit_castもある。間違ってダウンキャストを行おうとするとエラーになる。
>>678 確かに相互参照はマジでろくな事にならない。設計を見直して相互参照はなくすべき。
どうしても相互参照が必要な場合があるとすればObserverパターン位だと思う。そんなときはsignal/slotを使うことで明確化させる。
>>682 「わかってるねん わかってるねんで? バカにしたあかん
dynamic_cast が RAII ・・・それがごっちゃに・・・・」
違うとわかってても「あーるえーつー」って読んでしまう
相互参照はだるいっていうけどメディエーターとかないとゲームとか作れないじゃん NPCがプレイヤーやほかのNPC(たとえば一番距離が近い)を追跡するアルゴリズムとか メディエーターに問い合わせないとプレイヤーの位置とかどれが一番近いかとかわからないじゃん
>>690 相互参照が必要な場面があることと、相互参照がだるいということは両立するから特に問題ないと思うよ。
「なくすべき」まで言ってる奴がいるからこういう流れになるんじゃねーの
ヘッダーファイルhoge.hにて, グローバル名前空間に foo関数を以下のように定義することを考えます。 1:namespace NS{inline static int foo() {return 1;}} 2:namespace NS{static int foo() {return 1;}} 3:namespace NS{inline int foo() {return 1;}} この時, 1と3は同じだと考えて宜しいでしょうか? 2と1, 2と3はインライン化されるかどうかを除いては同じと考えて宜しいでしょうか? よろしくお願い申し上げます。
>>693 1 と 3 はリンケージが違う。 1 は内部リンケージで 3 は外部リンケージ。
ヘッダファイルで定義した場合、 1 だとコンパイル単位ごとに別物になるが、
3 ならすべてのコンパイル単位で同じ物となる。
2 と 1 はインライン化される(されやすい)かどうかを除けば同じことになる。
2 と 3 は、 1 と 3 と同様にリンケージが違う。
質問とは関係なさそうだけど、「グローバル名前空間に foo 」といえば ::foo のことに
なってしまうと思う。
695 :
693 :2009/09/26(土) 17:59:08
>>694 リンケージの差異ですか。
ありがとうございます。
「グローバル名前空間に foo 」は確かにご指摘の通りです。
失礼しました。
static関数の宣言の仕方は
staticの使い方3〜静的関数〜
ttp://www.paw.hi-ho.ne.jp/takadayouhei/technic/39.html ここにあるとおり
/* 静的関数の関数プロトタイプ宣言の例 */
static int testfunction( int value );
/* 静的関数の関数定義の例 */
static int testfunction( int value )
{
int a;
:
return a;
}
で良いとのことですが、inline関数の宣言の仕方は
同じく
/* inline関数の関数プロトタイプ宣言の例 */
inline int testfunction( int value );
/* inline関数の関数定義の例 */
inline int testfunction( int value )
{
int a;
:
return a;
}
で宜しいのでしょうか?
それともどちらか片方にinlineを付ければ宜しいのでしょうか?
(なお、inlineになるかどうかはコンパイラによってうんぬんはおいといてください。)
よろしくお願い申し上げます。
大学の講義でc++をするはめになったのですがCをある程度理解していることが前提でした。 Cは必修科目で一度やったからなのですが私はお情けで通してもらったようなものでCの知識がほとんどありません。 このスレのテンプレにあるような解説サイト読めばCの知識無しでも理解できますか? 今はスタック関数を動的にしてポインタでなんたら〜って問題で詰まってる感じです。 1回目にでた課題に10時間かけて半分も終わらない程度の能力なので 宿題をやってもらうスレに投下すると今後が思いやられるのでなんとか自分で理解したいのですが。
K&R第2版を買いましょう。たった200ページ程度で C言語のすべてがわかります。すべてです。
>>696 それでいい。最初に現れた宣言と矛盾の無い宣言を繰り返すのであれば問題ない。
>>698 K&R2 の読書会はどこぞでやってませんか。後ろ1/3 が全然理解できません。
付録Aとか。
いや、付録Bは異様に参照しています。
>>698 それ初心者には向いてないって意見もあるんだけど実際のところどうなの?
>>696 意味や動作上は問題ないんだけど、単純に分けて書くのは面倒だし、
離れた宣言の間で inline 関数を呼び出したときにはインライン展開が
起こりにくいなどのコンパイラ実装上の問題も考えられるので、
宜しくないと言えるかもしれない。
定義ひとつで済ませるのがおすすめ。
703 :
696 :2009/09/26(土) 20:49:13
704 :
659 :2009/09/26(土) 20:51:33
std名前空間で定義されたテンプレートの完全or部分特殊化に対して 言及しているC++の仕様書の項目を教えていただけますでしょうか? またはそれをコピペして示していただけますでしょうか? なお、英語でOKです。
>>704 17.4.3.1 Reserved names p1
>>697 お情けでC++の単位ももらえばいいんじゃないかィ
なにCの単位をお情けで取れたお前ならできる
お前はやればできる子だって俺はわかってるからよ
>>697 誰もが通る試練だ。あきらめずに続ければ物になるものだ。あきらめたらそこで終わりだぞ。
708 :
704 :2009/09/26(土) 22:46:04
709 :
704 :2009/09/26(土) 22:50:27
標準C++で、1ファイルあたりの行数制限はありますか?
そもそも規格上のソースコードにファイルという単位があるのかね。
ああ、確かにそうですね。 ありがとうございました。
g++でコンパイルすると、 文字コードがS-JISのソースで "能"が文字化けしてしまいます。 "能\"とすれば文字化けは解決しますが、 今度はVC++で困ります。 VC++では"能"で文字なく"能\"で問題が出ます。 これらg++とVC++で同時にこの問題を解決する方法は無いでしょうか。
EUC UTF8
16進 0x
>>714 --input-charset=cp932 --exec-charset=cp932
うにこーどをつかおーぜ。
入出力なんて英語でいいじゃん楽だし
720 :
714 :2009/09/27(日) 00:47:07
みなさんありがとうございます。
やはりUTF8等といったユニコードが必要なようですね。
しかし今までSJISの財産(負債とも言う)がたまっていまして、今更UNICODEにするわけにも行かないんです。
>>717 コンパイルオプションで指定できるのですね。
ありがとうございます。
逃げかも知れんが、 #ifdef __GNUC__ 何かする #else 同じようなことする #endif みたいな手もある。 コードに一切触るなとなると無理だけど、使える範囲は広い。
>>720 SJISで動作するやつはそのままでいい。
SJIS UTF8はコンパイラ文字をが認識するとき以外には影響ないだろう。
723 :
720 :2009/09/27(日) 10:41:37
>>721 ありがとうございます。
しかしそれですと将来的にコンパイラが変わったら
またメンテナンスしなければならなくなりそうで
ちょっと気が引けています。
>>722 そうですね。。。問題の起こるヤツだけUTF-8にすれば良いわけですか。
なるほど。
>>711 ファイルがなかったら、ファイルスコープの概念はなりたたない。
ファイルスコープなんていう概念は標準にあったっけ
翻訳単位だな でもファイル有効範囲という言葉はあった気がする
>>727 無いよ。
C の「ファイルスコープ」にあたるのは C++ では「グローバル名前空間スコープ」という。
実際にはstatic宣言次第ではファイルスコープが実現しているような気がするんだけど。 C++0xではもっと現実の実装へ歩み寄って欲しいなあ。
おまえら無名名前空間とかちゃんと使ってください
>>729 名前空間スコープでの static 指定で変わるのはリンケージ。スコープじゃない。
> C++0xではもっと現実の実装へ歩み寄って欲しいなあ。
何が不満なの?
732 :
729 :2009/09/27(日) 12:17:59
>>731 > 名前空間スコープでの static 指定で変わるのはリンケージ。スコープじゃない。
そういやそんな会話が上で交わされていたような気がするな。
> > C++0xではもっと現実の実装へ歩み寄って欲しいなあ。
> 何が不満なの?
インクルードパスを指定する方法とかが環境依存。
ディレクトリの区切りが/か\かとか。
一応ディレクトリが存在しない環境への配慮…(ryとかあるんだろうけどさ。
あとはexport。
>>732 > インクルードパスを指定する方法とかが環境依存。
最悪、ソースファイルに書かれたとおりで正しいファイルが選ばれるように
コンパイルオプションを調整すればいいわけで、あんまり問題だとは思わない。
そういった調整が可能なようにある程度ソースファイルを書く側で気をつけておく
ことになるんだけど、正直もう慣れたんであんまり問題だとは感じない。
boost レベルの汎用ライブラリが十分な移植性を持っていることを考えてもね。
> ディレクトリの区切りが/か\かとか。
#include で指定するパスに \ を含んでいると未定義動作になる。
単純に / で統一すれば良い。
> あとはexport。
これは確かに問題だと思う。
DR にもあった。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#820
>>732 環境依存のゴタゴタを避けたきゃJavaかC#に移行するって手も
そこまでするほどでもないならそれまでで
正直.netの文字列周りはうらやましいと思う
>>733 思う思わないの議論をし始めると不毛だから避けるとしよう。
俺だって全部/に統一しているしBoostも非常に便利に使わせてもらっているけど、
それとは別に仕様がはっきりと定めて欲しいなぁと「思った」だけのこと。
exportもまあ無くても慣れたけど
どうせC++0xという大改革をするなら
もうちょっとどうにかしてほしかった。
まあいいや
どうもありがとうね。
exportって、何すか? C++しかやってないから分からない。
templateメタプロを整理して言語として綺麗に見えるようにしてほしかった
>737 まぁネタだろうけど。 れっきとした C++ です。サポートしてる処理系が Comeau C++ ぐらいしかないけどな! >736 >exportもまあ無くても慣れたけど >どうせC++0xという大改革をするなら >もうちょっとどうにかしてほしかった。 C++0x としては何かするにしても deprecated 扱いにするとか削る方向しかないような気がする。 将来的にはパスあたりも含めて Modules in C++ TR で提案されるんだろうけど。
>>739 いや、素でそんなコンパイラは知らなかった。
ググってきたけど、プリコンパイルドヘッダみたいなもんか。まあ、あれば
便利だなとは思う。
Fortranの配列のアクセスに使える : みたいなものをC++で実装できますかね?
作れるよ。
BoostのRangeとかは便利だな
初心者なんだが string型の何文字目が○○か? みたいな関数ってある? もしくはint型の何桁目は何の数字か?とか
>>745 何がしたいの?
書いてあるとおりだとしたら、普通に書くだけじゃ何か不満なの?
>>746 ゲーム作り。二次元配列用意してマップ座標[0.0]番目の上に何が乗っているか?耐久力はどれくらいか?って事をやりたい
一桁目がそのマップにいる敵の種類二桁目がhpで・・とか。おかしい?
まじで手探り状態。多分こんな理屈じゃよくないんだとと思う
マジレスすると構造体とかクラスとか勉強しないとだめだと思うよ。
>>748 構造体はわかるけどクラスはいまいち知らん
勉強してきます
とりあえず入門書は最後まで読み終えてから質問したほうが効率がいいと思うよ。
>>749 > 構造体はわかるけどクラスはいまいち知らん
それ致命的だろ。
要するにC言語+一行コメントしか知らないと言うことにほぼ等しいよ。
C++は魔性の言語だから、まあ相当な覚悟が必要です。
趣味でやるなら真に覚悟を決めた者じゃないと
途中で挫折することは
間違いないから頑張ってください。
標準Cは1月で十分かなって実感できたけどC++は数年やっても終着点が見える気配すらしない
C++は定番の本を全部読むぐらいの意気込みで。デザインパターンの本も。 Cで巨大で複雑なことをやろうとすれば、どのみち自作C++に近づいていくので、 初めからC++を学んだほうが近道。
いや、最初はCだけで覚えた方が色々便利だと思うよ C縛りの仕事ってのはやっぱりあるし
それはそうかも。CとC++の違いを知っていたほうがいいかも。
ゲーム作りならC#でいいじゃろ。 C++使うほどじゃない。
C#でゲームなんか作ったら間違っても金は取れないわフリーでも相手にされないわ
>二次元配列用意してマップ座標[0.0]番目の上に何が乗っているか?耐久力はどれくらいか?って事をやりたい これで金を取るつもりか。
C縛りの仕事なんてやりたくないわな
計算量が必要な処理は何でもGPUみたいな時代になりつつあるし、 そうなったらWindowsで作ってる分にはC#でいいな。
まぁ、Windows限定でならそれでいいんじゃね。
>>745 ちょっと書いてないみたいなんで
> string型の何文字目が○○か?
単純に文字配列的に使える s[n] みたいに。
> もしくはint型の何桁目は何の数字か?とか
こっちは知らん。自分で関数書くのかな。簡単だしいろいろな書き方ありそう。
xのn桁目は x / (10のn-1乗) % 10 で求められるよ。
> > string型の何文字目が○○か? > > 単純に文字配列的に使える s[n] みたいに。 実のところ、そう単純ではなく、 stringにSJISなどの二バイト文字が入っていると 何文字目と何バイト目の対応がずれるし、 UTF-8が入る場合もある。
int getNthDigit(int x, int n) { char buf[100]; sprintf(buf, "%99d", x); return buf[99 - n] - '0'; } // いまいちすっきりしなかった
>>759 組み込み系では今でも多いんじゃない? 現場から離れたので詳しくは知らないが。
C++は、仮想継承等、表に見えないデータ量増加等があって、知識がないと嵌るかも
しれないし。
>>757 一方、iPhoneは・・・いや、なんでもない。
>>723 SJISのままできるよ。
SJISソースの文字の2バイト目に\がくる場合に\\に
置き換えるフィルタをC++で作ればいいよ。
>>769 サロゲートペアとか結合文字とかあるから、だめなんじゃないの?
wchar_tは存在自体が邪悪
772 :
デフォルトの名無しさん :2009/09/28(月) 23:57:34
c++の言語仕様について詳しい方、お願いします。 (unsigned int)-1 -(unsigned int)1 -1u これらは、unsigned int であらわせる最大の値であることは保障されますでしょうか? それとも環境依存or不定でしょうか? C++0x ではなく ISO/IEC 14882:2003 でお願いします。
>>771 邪悪だろうがvector<bool>だろうが、
標準に入っちまえば正義。
光(移植性)あるところ常に影(ツギハギ)あり
>>774 すみませんが
他の方法ではなく、
質問そのままの方法で回答がわかる方お願いします。
そりゃあ…かまわない おまえの質問に答えること それ自体は容易い 簡単だ 規格はこれこれこう そんな話は いくらでもできる しかし 今 オレが そんな話を 仮にしたとしても その真偽はどうする…? 真偽など どうでもいいから 聞きたいと言うのか…?ククク……
つまり、既存コードでそれがあって、そこが問題の原因になってるかどうかを知りたい?
>>777 ご存知でしたら教えてください。
真偽はあなたを信用しますとしか言えません。
もし可能であれば規格の根拠となる部分を教えて頂けたらと思います。
>>778 そのように思っていただいてもかまいません。
詳細はすみませんが控えさせていただきます。
>>773 標準はあくまでも標準でしかなく正義ではない
邪悪の反対は善良であって、正義ではない。
C++は数値の内部表現については規定してない。 そしてそれ故負の数が補数で示されるかどうかなどは分からない。 保障されない。
とりあえずその処理系について、最大値と同じ値になるかどうかを調べてみたら? 既存システムの問題判定のためにはそれでいけるとおもうが、詳細(というか、状況)を伝えられないのなら これ以上はむりだわ
wchar_tは粘着アンチがいるなぁ 普通に使えるところでは使える 使わせる気がさらさら無い環境も少なくはないが
>>772 unsigned intの算術はmod 2^sizeof(unsigned int)の世界に常に従うから
その3つはどれも2^sizeof(unsigned int)-1になることが保証されてる
不定だの処理系定義だの負の数の内部表現に依存するだのデタラメ言ってる奴らは自重しろ
訂正 2^(sizeof(unsigned int)*CHAR_BIT)だな
787 :
デフォルトの名無しさん :2009/09/29(火) 02:22:37
世界はもうやめろ
ああ違う違う何言ってんだ (unsigned int)-1 これはunsigned int型の2^(sizeof(unsigned int)*CHAR_BIT)-1 -(unsigned int)1 -1u この2つはsigned int型の-1になる またunsigned int型に変換すれば2^(sizeof(unsigned int)*CHAR_BIT)-1になるけど
知らなかった ごめんなさい
謝るほどではないw
>>780 標準は正義では無いだろうが
勝者は正義と見なされる。
そして標準は勝者である。
標準は勝者かな? 標準と聞いて俺が思い浮かべる言葉は主に妥協とか公約数で、 「勝」の字に見合うイメージはあまり無いけど。
basic_string<> に、ちょっと機能(例えば文字コード変換だとか)を追加したような文字列 クラスを作りたいのですが、どうすべきか迷っています。 最初、安直に basic_string<> を継承しようかと思ったのですが、デストラクタが virtual じゃ ないんですね。 basic_string<> をメンバーに持つクラスを作るという手もあるかもしれませんが、 基本的なインターフェースを basic_string<> と同じにしたいというのがあるので、 それを自分で一通り用意しないといけないですよね。単純作業かもしれませんが。
string conv(string, option)でおけ。手間かけて得られる物は少ない。
そういう機能は普通の関数にしとけ
>>790 人の事を散々出鱈目だのなんだの言っておいて謝っただけで済むと思うな。
何を勘違いしてるんだ。 謝らなくても済む場所で、わざわざ謝ってもらったんじゃないか。
盛りあがってまいりました!
足し算のみだと、char , short int , int(float) , doubleの順に時間掛かるな。 サイズに応じて掛かる時間が比例する。 char で1秒かかるとき、doubleだと8秒かかる。 forでカウントするときは、適切なサイズを用いた方が良いらしい。 unsigned intが最も速いんだと勘違いしてた。 intに変換し直すと思ってた。
メモリは余分確保しない方がいいってことだ。ここを見直すだけで、速度が倍になったりする可能性がある。
>>800 環境依存だから、環境を特定して言わないと意味無いよ。
しかしループカウンタに char を使ったほうが速い環境ってどんなだろう?
8bit CPU 向けコンパイラでカウンタの最大値が 256 未満とか?
別方法で計測したら、char 2000とすると、double 3700くらいだった。順番は変わらず。
8倍の部分の訂正。
>>802 カウントを256未満しか使わない場合。環境はx86 windowsXP。
いまの計測方法は、vector< int > vec(100000);という配列にランダムアクセスが来て vec(・)++; とカウントしたときに合計時間です。
>>798 >謝らなくても済む場所で
それを許すから便所の落書きになる。
え?ここって便所の落書きコーナーじゃなかったの?
>>806 許す許さないはこの話に全く関係無い。
試しに今、
>>790 をずっと許さないでいてみな。それが便所の落書きを
何か上等な物に昇格させるってんなら、見ててやるよw
俺は「C++関連の便所の落書き」が「C++の話すらできない便所の落書き」に
ランクダウンするだけだと思うけどね(人それを「荒れる」と言う)。
関数にデストラクタがあったらいいのだが・・・ 関数を使ってバッファ付きファイル出力したら、 終了時にバッファの残りを出力しないといけない。 クラス化するのも面倒。
flush ではダメなの?
>>809 それは関数の最後に処理を記述するのと何がちがうの?
>>809 ・関数の最後に出力処理を書き、その直前にラベルを置く。ショートカットしたいときはgotoする。
・その関数を呼ぶだけの関数を用意し、その関数で出力処理を書く。
・関数内で無名のクラスを作り、デストラクタで出力する。
C++でUTF32の文字列を扱おうとしたら どうやるのがセオリーなんですか?
従来の文字コードと大体似たように扱えばおk wchar_tがUTF32な環境限定で作るのが確定してるならwchar_tでもおk
そもそもC系言語で日本語文字列を扱わないのがセオリー
>>813 32bit 整数型( uint32_t とか)を符号単位として typedef して
std::basic_string とかの標準コンテナを使って文字列型を作り、
各種変換関数を用意する、って感じ?
自分の使った方法と、それについて具体的に不満な点を挙げて
もらったほうがいいと思う。
817 :
809 :2009/09/29(火) 14:46:56
すみません。こういうケースなんです。 fwriteはバッファがたまったら出力します。staticやグローバルでメモリを確保します。 main(){ while(){ ・・・ fwrite( x ); } }
RAIIを徹底せよ
819 :
809 :2009/09/29(火) 14:52:09
fwriteでstaticでクラスのオブジェクト生成すれば、いいですかね? mainの終了時にデストラクタよばれますよね
>>813 ICU使うのが一番簡単なんじゃないかな
>>816 > 自分の使った方法と、
UTF32の文字列を使ったことはありません。
> それについて具体的に不満な点を挙げて
不満な点ですか?
どのOSでも同じように使えないのはイヤ。
フレームワークを使うときは、そのフレームワークにあわせますが、
使わない場合のやり方がほしい。
なるべくC++標準のやり方がいい。(C++0xではu32string?なんてのができるの?)
それが無ければ準標準(boostみたいな)のやり方、
それが無ければ、クロスプラットフォームなライブラリ(有名なもの)
>>817 そんなアプローチでいいとは信じ難いのだが……
それはさて、staticなオブジェクトのデストラクタは呼ばれるよ。
exception含めて例外処理ができなくなるけど。
823 :
デフォルトの名無しさん :2009/09/29(火) 15:33:25
なるほど
std::stringにヌル文字入れられるみたいなんですけど どうやって入れるのでしょうか?
0
proxyってようは参照っぽく振舞うオブジェクトのことでいいの?
827 :
デフォルトの名無しさん :2009/09/29(火) 17:56:57
もしかしてクラスのメンバー関数に可変長引数を使うのはNGなんでしょうか? AAA: texture (char* name, ... ) みたいな感じで定義すると va_args の戻り値が 有効な引数の数を越えて呼び出しても0になってくれないのですが… (ので引数の数が判定できない)
有効な引数の数を超えて呼び出したら0になるなんて、誰からそんな嘘を聞いたんだ?
夢じゃないかな。
830 :
827 :2009/09/29(火) 19:06:41
いやPixieというとてもとても有名なフリーソフトがそうやってるのですが… // Comments : static inline void getArgs(va_list args) { RtToken tmp; tmp = va_arg(args,RtToken); nTokens = 0; while (tmp != RI_NULL) { // tmp = va_arg(args,RtToken); }
833 :
827 :2009/09/29(火) 19:26:54
ごめん、Pixieには可変長引数の関数を呼び出すときは必ず最後0を入れて呼び出す、 という決まりを忘れてました。うっかりさんです。 解決しました。 このうっかりは検出できねー
834 :
827 :2009/09/29(火) 19:27:54
いい忘れ。 ありがとうございました。
835 :
デフォルトの名無しさん :2009/09/29(火) 20:03:43
A g_a; A& get_A1(){ return g_a; } A get_A2(){ return A(); } main(){ const A& a = get_A1(); // OK const A& a = get_A2(); // ? } こういう風に、インスタンスを返す関数に対し、参照で受けても問題ないでしょうか?
>>827 定義するのも使うのも構わないけど
非PODを省略部の実引数に渡すと未定義動作だから気を付けろ
>>836 ありがとうございます。
やっぱり、「const A a = get_A0();」
よりは、「const A& a = get_A1();」の方が
代入が無い分、効率が良かったりするんでしょうか?
今まで書いたコードは全部前者なんですが、失敗したかなぁ?
const参照ならテンポラリな返り値を受け取ってもいいのかしらなかった
RVOだかNRVOだかでヤフれ
>>840 NRVOはVC8で有効なようで、
自分の環境では前者でもいいみたいです。
ありがとうございました。
>>838 とりあえず一定以上の品質のあるコンパイラに
最適化させればそのくらい空気読んで
戻り値最適化をしてくれるから
今までのでも大丈夫だと思うよ。
>>833 vectorやfusionで渡すといいよ
vector<string>、vector< vector<int> >型をファイルに記録するとき、 サイズなどの情報を含めて、HDDのイメージバックアップのように記録できませんか?
boost::serialization
thx
>>813 正式にはstd::codecvtをカスタマイズするのだと思う。
ただめんどくさいし実用性が怪しいので誰もやらない。
やはりMFCやらQtやらのフレームワーク又はICUなど
の外部ライブラリを利用することになるはず。
後、boostの一部はロケールをあんまり考慮してないの
ではまる可能性有り。
boost::lexical_castはグローバルなロケール使ってるか
らドボンし易いのだけど、これを内部で利用しているもの
が色々あるので困る。
boostでロケールが絡むものは避けた方がいいかも。
lexical_castは最初は神だと思ったなぁ… 今でも用途さえ合えば神なんだけどね。 C++がゼロオーバーヘッドを正義としている以上、ライブラリも同じ正義をおおむね 目指している訳で、抽象度と汎用性の高いライブラリでも「それがどんな仕組みで 動いてるのか」を把握した上で使う前提になってるのが、良さでもあり悪さでもある んだろうなぁ。
欧米人はロケールに全然興味なさそうだよね。 まあ、わかるがw。
>>847 やっぱ、セオリーといえるほど一般化した方法はないんでしょうかね。
今回自分がやっていたのは、ある海外ソフトの日本語化なんですが、
フレームワークはそのソフトが使っていなかったので
そこまでやりたくなかった。
そうなるとICUかiconvかってことになるわけで、なんとなくiconvを選んでみました。
文字コードだけじゃなく、本格的な国際化するときはICUがいいんでしょうね。
それでstd::basic_string<uint_32> u32stringがC++0xで標準になるって
みたんで、u32stringを使うことにしました。
あとは、iconvのchar*のデータをu32string型に入れるとこなんですが、
さてどういうやり方が一番シンプルなんだろうか。
ICUのほうがいい。 変換時に、バグってる文書でも、なるべく多くの情報が残る。 NKF ICU ICONVで比較した。 ICUだけがダントツで性能良かった。
ICUってスレッドセーフ?
ぶっちゃけ、コンピュータを扱う時点で英語以外はディスアドヴァンテージしかない。 英語以外はテキストでなく、特殊なバイナリデータとして扱うぐらいの気持ちでいる必要が。
854 :
デフォルトの名無しさん :2009/10/01(木) 19:11:16
http://codepad.org/cBQ6OsB3 このプログラムですが、printfで出力される値と
fprintfにより算出される値が異なってしまいます。
特にfprintfにより出力される値は異常値になってしまいます。
どうか、ご教授のほどよろしくお願いします。
doubleにカッコがなくてエラーででるじゃん
それとdoubleなら%lfね。%fじゃないよ
以下857がネタを提供してくれます。
>>850 C++0xのu32stringはstd::basic_string<char32_t>
UTF32を扱う(操作する)だけなら、32bitの配列に入れれば良いだけ。 コンバートしたりするなら、言語処理のプログラムが居る。
862 :
デフォルトの名無しさん :2009/10/01(木) 21:30:05
イテレーターで一つ前の要素を使うにはどうしたらいいですか? x_new = x_old + dt*v_old みたいに
ひとつ前の要素を覚えておけばいいじゃん
u32string str = "abc"; これ動かないよね。 もちろん、 char *str = "ファイルから読み込んだテキスト" u32string text = str; も
>>865 u32string str = U"abc";
下はファイルから読み込むときにchar32_tで読んどけばいい
残念ながら、外部APIの仕様でcharに入っているんだ。 だからcharからu32stringに変換しないといけないんだよね。
それは標準の範囲では難しいな…
いったん、charでファイルに書き出して char32_tで読み込むとかw
for (xo = x; x != e; xo = x++) *x = a * *xo + *v++;
どこが?
型が書いていない。
いきなりfor文書いたら、そりゃコンパイルエラーだろうよ。
ぶっちゃけ何のコードかもさっぱりだw
宣言なしで新しい名前を使ってるからC++ではないな
実はプリプロセッサ
>>851 > 変換時に、バグってる文書でも、なるべく多くの情報が残る。
それは、エラーになるべきじゃないの?
そんなの場合によるだろうに。 少しのエラーなら無視して読み続けられる方が都合のよい場合もある
少々バグってる文章ですぐエラーになる仕様のブラウザがあったとしたら、 そんなの使ってられないだろうな。
RSSリーダでマルチバイト文字が途中でちぎれてる文書に出会ったときに全部読めなくなるのとかは結構存在する。
class で[] を演算子に使ったときに、代入は出来ないんですか?
[ n ] = x という演算子が出来ればいいのですが。
方法1: [] 演算子で、参照を返す 方法2: [] 演算子で、代入演算子をオーバーロードしているクラスを返す
>>886 A[n] の参照には直接代入できない場合にやりたいのですが、方法2だとできますか。
あと、値読み取りも出来るようにしたいんです。
bitsetの様に、A[n]の読み取り書き込みがしたいです。
bitset の実装を読めばいいと思います bitset の operator[] は bitset::reference というクラスを返す こいつは operator=(bool) や operator bool を実装しているので、bool を代入したり bool に変換したりできる
サンクス でも面倒そう、間違えそうなので、add(n)というメンバ関数で済まそうと思いました。
プライベートメンバへのポインタを戻り値として戻すメンバ関数の作成を禁止する文法とかってありませんか・・・
>>884 こんな感じかな
template <class T>
class proxy
{
public:
proxy(T *p) : p_(p) {}
void operator = (const T &t)
{
*p_ = t;
}
operator T ()
{
return *p_;
}
private:
T* p_;
};
class hoge
{
public:
proxy<int> operator [] (unsigned i)
{
return proxy<int>(&a_[i]);
}
private:
int a_[10];
};
>>862 その反復子が双方向反復子として使えるならboostのpriorで取得できるよ
895 :
デフォルトの名無しさん :2009/10/02(金) 21:52:16
C++初めて三日です。分からないとこがあるのですが #include<stdio.h> //グロバース変数 int globalx; void Func(){ ←この部分のFunc01()に何の意味があるのですか? glpbalx=10; } int main(coid){ Func(); ←それとこの部分のFunc01()にもなんの意味があるのですか printf("%d",globalx); } すみません初心者で
>>895 > //グロバース変数
グローバル変数かな?
> int globalx;
> void Func(){ ←この部分のFunc01()に何の意味があるのですか?
Func01 なんて無いんだけど…
Func 無しでも初期化はできる。
> glpbalx=10;
globalx=10; かな?
> int main(coid){
coid→void かしらん?
> Func(); ←それとこの部分のFunc01()にもなんの意味があるのですか
Func01 なんて無いんだけど。わからないなら抜いて見ればよろし。
これを入れないと globalx は初期化されない。
C++ なのに C コードだけなのは何故なんだろう。
>>895 致命傷過ぎる
何なんだバカにしてんのか?あ?
C++はCの一部を含んでるから、Cコードだけってのはナンセンス。
>>899 別にいいんだけど、C++ なら敢えて cout 使わずに
printf 使うのはなぜかな、とは思うな。
来世でも言い続けますが何か?
903 :
デフォルトの名無しさん :2009/10/02(金) 23:26:28
>>896 ありがとうございました
これからも分からなくなったら来ても良いですか?
だめだ 少しは自分で調べろ 調べてわからなかったら来ても良い ただし何をどう調べてどうわからなかったか書くこと
ノートに書き写した授業の課題だな。
907 :
901 :2009/10/02(金) 23:42:13
ならいいんだ。
ていうか、
>>895 のC++の要素ってFunc(){}で引数省略してるくらいなんじゃ。
>>850-852 ICU なんてモノがあったんですね。初めて知りました
これまで nkf や iconv だけだったので、ありがたいです
知ってるよ
嘘じゃないよ!
916 :
デフォルトの名無しさん :2009/10/03(土) 16:31:30
次のエラーが出てしまって困っています。どうしたらいいでしょう? Visual C++ 2003では使えたらしいですが、Visual C++ 2008でやるとこの エラーが出てしまいます。よろしくお願いします。 error C2327: 'Multivac::CInitialCurve<T>::Curve' : 型名、スタティック、または列挙子ではありません。 コンパイルされたクラスの テンプレート のインスタンス化 'Multivac::CSetOfPoints<T>' の参照を確認してください
917 :
916 :2009/10/03(土) 16:39:28
エラー箇所を示します。 template <class T> class CSetOfPoints: public CInitialCurve<T> { protected: Curve<T> Front; ←ここでエラー
918 :
916 :2009/10/03(土) 16:42:28
関連してそうなところも示します。 template <class T> class CInitialCurve { /************** * ATTRIBUTES * **************/ protected: Curve<T> Curve; template <class T> Curve<T>::Curve() throw() { n_=0; orientation_ = -1; }
920 :
916 :2009/10/03(土) 17:00:26
>>919 ヘッダファイルなどがあったのでそのフォルダにはパスを通しましたが
ライブラリファイルらしきものは無いので他はやっておりません。
921 :
916 :2009/10/03(土) 17:08:49
関連ありそうなところとして次もあげます。 template <class T> class Curve { /************************ * TYPEDEF DECLARATIONS * ************************/ public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference;
本当にエラーが出た場所はそこなのか気になる。 VC++ .NET 2003→2008でそのエラーなら、まず疑うのはtypenameを付けていないことなんだけど、 さすがにそこはtypename要らない場所だから。
923 :
916 :2009/10/03(土) 17:35:09
>>922 他にも似たようなエラーが916のエラーの後にもあるので示します。
error C2327: 'Multivac::CInitialCurve<T>::Curve' : 型名、スタティック、または列挙子ではありません。
error C2327: 'Multivac::CInitialCurve<T>::Curve' : 型名、スタティック、または列挙子ではありません。
template <class T>
class CSetOfPoints: public CInitialCurve<T>
{
protected:
Curve<T> Front; ←
>>916 のエラー
//! Is the bottom left corner outside the front?
bool origin_out;
public:
CSetOfPoints();
CSetOfPoints(Curve<T>& InitialFront); ←ここでのエラー
CSetOfPoints(string InitialFrontFile, int orientation, bool origin_out_);
~CSetOfPoints() throw();
924 :
916 :2009/10/03(土) 17:37:40
もう一箇所あるので示します。 それぞれのエラーがどう関係しているのかよく分かりませんが・・・ (1) error C2061: 構文エラー : 識別子 'Curve' (2) error C2995: 'Multivac::CSetOfPoints<T>::CSetOfPoints(void)' : 関数テンプレートは既に定義されています template <class T> CSetOfPoints<T>::CSetOfPoints(Curve<T>& InitialFront) ←(1)のエラー { Front.Copy(InitialFront); origin_out = true; }←(2)のエラー
それは2003でコンパイル出来たソースに全く手加えてないのが通らないの? それとも新規に書いたとか、手加えたものが通らないの? テンプレート使いまくったコードは断片的にコンパイルエラーとかソース見せられてもわからんよ。 使用側がミスってるだけでも、ライブラリ内でエラーでまくるしな。 あと、テンプレートクラスのエラーはエラー一覧じゃなくて、 出力の方でエラーの詳細でコンパイラがどうインスタンス化しようとしてんのか見ないと。
926 :
916 :2009/10/03(土) 17:57:24
>>925 全く手を加えていない状態です。
すみません。テンプレートなるものを初めて知ったもので・・・。
インスタンス化の詳細とかってvisual studio 2008で、
どうすれば見れるのでしょう?
エラー一覧とか並んでるタブの中に出力ってのがあると思う。 エラー一覧ではライブラリ内でエラーってでるけど、出力の方見ると 理由: 'int' から 'const DisplayMode' へは変換できません。 コンストラクタはソース型を持てません、またはコンストラクタのオーバーロードの解決があいまいです。 d:\include\boost-1.3.9\boost\bind\bind_template.hpp(61) : コンパイルされたクラスの テンプレート のインスタンス化 'R boost::_bi::li(略)' の参照を確認してください with [ R=bool, ←テンプレートの実引数 A1=boost::arg<1>, A2=boost::_bi::value<int>, T=bool, ..... みたいな感じでずーっと並んでると思う。 これを辿っていくとそのエラーの最後の方に自分の書いたソース名が見つかるはず。 d:\myproject\mysource.hpp(120) : コンパイルされたクラスの テ(略 ←ここが本当の原因 これがテンプレートライブラリ使ったときのコンパイルエラーの読み方なんだけど、 全く手加えてないんなら単にライブラリに問題があるのかもね。
928 :
916 :2009/10/03(土) 19:10:30
>>927 ありがとうございます。
どうにか解決できました。
エラーの'Multivac::CInitialCurve<T>::Curve' の
CurveというクラスがCInitialCurve<T>クラスにもメンバとしてあるのですが、
Multivac空間内に直に定義されてもいて、
Curve<T> Curve; を
Multivac::Curve<T> Curve;
としてやることでエラーが無くなりました。
他のエラーも 同じことをしてなくなり、
実行結果も正しく得られるようになりました。
明らかにクラスのオブジェクトを宣言している文なのだから、
名前空間いらないんじゃないかと思うのですが・・・。
>>928 これが通らないのと同じことかな。
struct a {};
struct b { a a; };
コピーコンストラクタについてなんですけど not const(not const) 可 const(const) 可 not const(const) 不可 const(not const) 可 といったように(参照のコピーコンストラクトのように)const性で処理を分岐させることは可能でしょうか?
>>930 よく分からない。もう少し具体的に。
コピーコンストラクタというのは↓のようなもので、引数はconst参照以外ない。
hoge(const hoge&);
Effective C++ 3版をよんだんですけど、 これ以上の知識が無くても大丈夫ですか? modern C++ design とかも読まないと駄目ですか?
>>931 コードで書くと↓みたいな感じで。ようは参照っぽく振舞うProxyを作りたいんですが・・・
class Hoge {・・・};
Hoge h;
const Hoge ch;
Hoge h1(h); // ok
Hoge h2(ch); // error
const Hoge ch1(h); // ok
const Hoge ch2(ch); // ok
>>934 class Hoge {
private:
Hoge(const Hoge& hoge);
public:
Hoge(Hoge& hoge);
Hoge(Hoge& hoge) const;
Hoge(const Hoge& hoge) const;
};
これじゃだめ?
コンパイル通るか試してないけど。
936 :
935 :2009/10/04(日) 15:19:31
>>934 コンストラクタにconst属性付けるのはNG
多分本当にやりたいことはこんな感じじゃない?
class HogeImpl; // 内部実装
class ImmutableHoge // 変更不可能なHoge
{
public:
ImmutableHoge(const ImmutableHoge& rhs);// ok const(const)に該当 (copy constructor)
ImmutableHoge(const Hoge& rhs);// OK const(not const)に該当
HogeImpl* pimpl;
};
class Hoge // 変更可能なHoge
{
Hoge(const Hoge& rhs); //OK not const(not const)に該当 (copy constructor)
private:
Hoge(const ImmutableHoge& rhs); // NG not const(const)に該当
HogeImpl* pimpl;
};
Immutableは当然中のデータが変更されない/できないように実装する。
デザパタ的にはImmutableパターンとかいうやつ?(GoF本しか持ってないからよく知らないけど)
constは「その変数を通しては中身を書き換えない」という意味で、インスタンスの不変性は保証できないよ。
それにクラス内部で自分がconstかどうか判別する方法もないと思う。
それを使って何がしたいのかが説明されてないからあってるかわからんが、 引数が非constの時とconstの時で使われるコンストラクタを分けたいなら 右辺値参照(rvalue reference)とかmove semanticsとか Boost.Moveでググると良いんじゃないかと思った。
939 :
939 :2009/10/04(日) 17:06:41
ああ、ちょっと上に書いてあったか まったく的外れだった
>>932 Effective C++ を読んで、その内容に納得できるなら良いと思うけど。
例えば、他人に説明できるレベルとか。
いずれにせよ、そんなことよりコード書かなきゃいつまでたっても
書けるようにはならん。知識だけではコードは書けない。
本の内容もコード書いていなければ実感できない。
あるクラスの全メンバを、一気にゼロで初期化するにはどうすればいいですか? Cのmemset(ptr, 0, size)のC++版が知りたいです。 memsetはvtblまで0にしてしまうから駄目という所までは調べて分かりました。
自分で作ったクラスで無いなら、カプセル化に反するから普通の方法じゃ無理 自分で作ったクラスでそういうことがしたいなら、 普通はコンストラクタで明示的に書く それが面倒なくらいメンバが多いようなら多分設計を見直した方が良い まあ、恐らく組み込み型の初期化についての話だと思うから、 boost::value_intializedについてググると良いんじゃない?
>>941 初心者歓迎のスレの人だよね?
普通のクラスの初期化の場合、ゼロで初期化する必要は全くない。テンプレートで
汎用的に作るのなら尚更。だから、この件はデフォルトコンストラクタが走った
オブジェクトを代入で十分だよ。
>>941 そのクラスがPODならmemsetしてもいい
PODについてはめんどくさいからぐぐれ
>>945 そういうのもなんか気持ち悪いよね。
明示的にPODを示す構文があるべきだったかも。
pod_structとか
>>946 基本的に素人お断りな言語なので不要だと思います
いやならJavaとか使えばいいわけだしね
そのうちこれが出来るようになるから static_assert(std::is_pod<Hoge>::value, "not POD");
memset使いたいがためにTMPかよ
無駄にゼロ初期化に拘ってるだけでしょ。
TMPは絶対的正義だから仕方ない。
コピーできないポインタみたいなのを作りたいんですけど どんな方針でやるのがいいんでしょう?
boost::scoped_ptrじゃダメなの? >952
boostが使えない環境もあると思うのですぐにboostに頼るのは避けたいです
>>954 ほんなら適当なクラスに->オペレータとプライベートなコピーコンストラクタでも定義したら?
boostが使えないってのは組み込み系の話ですか?
Boostが使えないとか、元STL系ライブラリも駄目とか言いそうだ。
テンプレートの<>記号が出てくるとみんなが怯えるんです
テンプレートのないC++を使うくらいならC#を使いたいぜ
>>961 新スレの 1 がテンプレさぼったみたいなんで補完しようとしてて、
>960 はそのときの誤爆。
せっかく短くしてもらったけど Books はもう貼り終わってた。
次スレの終わりあたりでまた書き込みしてもらえると助かる。
いま
>>4 のリンク先確認が済んで書き込みしようとしたら、連投規制で
詰まってる。
static_assertしなくてもenable_ifとis_podでいいんじゃね
>>967 そのページ、使いやすかったんで残念。
つーかSTLでググると、リファレンスへは飛ばずに
糞みたいな日記ばかりヒットするのは止めて欲しい。
残存と追加で同等以上のページをつくれ
web.archive.orgからサルベージしてローカルに保存したよ 角さんのページじゃないと駄目なんだ俺
c++ではマクロを使う場合inlineを使うみたいなんですが、 #define TEST( x ) "%d",x これをinlineにできますか?
あ?
>>972 マクロは使える。
マクロはinlineに置き換えた方が良いだけ。エラーの特定などのため。
必須ではない。
保守性無視しても効率高めたいなら、マクロの方が良い。 確実にコード内に埋め込めて、関数呼び出しのコストがない。 なるべく使わないが良いけど、用途次第。 forは展開出来ないとか。
>>975 キャッシュって知ってるか?
必ず効率が高まるわけじゃないよ。
関数にしてコンパイラにまかせるのが正解。
どうしてもヘッダに定義をおきたいときに inline を使う。
必要性と計測に基づかない最適化は悪。
> 必要性と計測に基づかない最適化は悪。 これは、ちょっと、言いすぎだな。 × 〜悪。 ○ 〜保守性を損ねる理由としては不十分。
>>972 できないのでそのままにしておくか、それを捨てるか。
>>972 そのマクロどうやって使うの?
printf(TEST(x)) とかやるの?
それなら普通の関数 print_int(x) でいい、っていうかこっちのがいいよね。
inline にする必要も無い。
ばか
すみません。質問良いですか。 char *p = new char [1000]; このようにメモリを確保して、たとえば、char *q = &p[500]; delete q; とすると、メモリは解放されますか?
いいえ それは未定義の動作です
クラスのメンバ変数 char *qで、他所で確保されたメモリのアドレスを保持する場合と 自前で確保した場合があり、後者のみデストラクタでメモリを解放したいのですが。 他所のだけ解放し無いように出来るんですか?
配列を解放するにはdelete [] を使えって意味じゃないの?
そのクラスにもうひとつ bool qIsFromOuter; のようなメンバ変数を増やして、 q が他所で確保されたか自前で確保したか覚えておけば、出来ます
トンクス
Java謎落とし穴という書籍の中でC++に関するマニアックな記述があり、どうしても理解できない部分があるので教えてください。 「class Point{ int x; int y;} というクラスがある時、 ローカル変数 Point p; を宣言すると、Javaではpは参照になるがC++ではPointオブジェクトの実体が格納される変数になります。」 と、ここまでは分かるのですが、次の文が分かりません。 「よってC++では、ただPoint p;のようにして変数を宣言しただけでもコンパイラはそこにコンストラクタを呼び出すための機械語コードを生成します。」 Point p;と宣言した時点ではPointを格納できるだけの領域を用意すればいいだけであって、コンストラクタを呼び出すのは実際にnewする時なんだから 変数宣言時にコンストラクタの呼び出しコードなんて知らなくてもいいように思うのですが、間違ってますでしょうか?
>>987 Point p;
に対して何をどうnewするつもりなんだ
>>987 これはテンプレに入るレベルのJava脳www
ローカルで Point p; とすればそれは宣言ではなくpの定義で実行時はそこでインスタンスを生成するだろ。 最適化がからめば実際のインスタンスの生成はpを参照する直前になるかも知れんがそれは別の話。
彼はたぶんC#と間違えているんだろう
992 :
987 :2009/10/06(火) 15:33:16
回答ありがとうございます。 Point p;が定義であっても、Pointを格納できるだけの領域(ここではxとy)を用意すればいいだけで、 Pointがどのように作れれるかといったことは知らなくてもいいと思うのですが。 関数の外でnewされて引数として渡されてローカル変数pに代入される、ということを考えた場合、 コンパイラにとっては関数内でコンストラクタの生成コードなんて知らなくてもいいはずです。
文字コードの判別ってみなさんどうやってるんですか? ICUで出来るらしいですが、VC++でコンパイル通りません。 nkfだと日本語しか出来ません。するとやるやつがないです。
994 :
993 :2009/10/06(火) 15:40:32
これだけで構文エラーになるんですが。 ライブラリのセットアップはしてあります。 #include <stdio.h> #include <unicode/ucsdet.h> int main() { return 0; }
>>992 だから、アンタはC++に関しての知識が無さすぎる。
本当に知りたいのならC++の入門書を読むべきだし
Javaを学んでいる途中で気になっただけなら、
「自分はC++の知識不足で理解出来ない」として読み飛ばしておけばよい。
>>992 領域を用意するだけじゃなくてインスタンスを作るの。
インスタンスを作るためにコンストラクタを呼ぶの。
そんだけ。
>>994 それでエラーって、コンパイル環境ができてないんじゃ。
つかエラーって何よ? <unicode/ucsdet.h>にインクルードパスは通ってる?
ICU知らないけど。
コンストラクタを呼ぶことによってカプセル化されたクラスとしての整合性を 取ることができるようになるのであって、ただ領域を確保するだけだったら C時代の構造体と変わらなくてクラスの意味がない。
>>992 値型と参照型について調べれ。
二つの違いが分かれば、
>関数の外でnewされて引数として渡されてローカル変数pに代入される、ということを考えた場合、
が、いかにアホな事言ってるか理解できる。
ヒント:Javaの変数は全て参照型
あんまりJava脳とか言い過ぎるとアンチC++を無駄に増やすだけだろ…
Javaとはnewの意味が違う。
C++はそういう定義をしたら、その時点でそのインスタンスは普通に存在
するし使える。領域確保だけじゃなくて初期化も全てされる。
>>992 の思ってるような、領域だけ取って後からnewで生成、という分割
した初期化構文もあるけど、それはplacement newといって、若干高度な
話。
ああ逆か。
>>992 はあらかじめ外でnewされてると思ってるのか。んじゃ
placement newの話は無しで。
とにかく、JavaとC++はnewの意味が違う。newは普通は極力使わない。
new演算子をカスタマイズしてバリバリ使う場合もあるけど。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。