STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
前スレ
>>994 std::multisetのoperator>は任意のクラスの比較オブジェクト若しくは
比較関数を定義する時に用いる
挿入順序を決定する
struct Set {
int a;
double b;
Set(int i, double d) : a(i), b(d) {}
};
bool operator>(const Set& a, const Set& b) {
return a.b > b.b;
}
int main()
{
std::multiset<Set, std::greater<Set> > ms;
ms.insert(Set(1, 2.0));
ms.insert(Set(2, 1.0));
for (std::multiset<Set, std::greater<Set> >::const_iterator pos = ms.begin(); pos != ms.end(); ++pos)
std::cout << pos->a << ' ' << pos->b << std::endl;
}
但し次のような例ではstd::greaterを定義していても暗黙の内に <()std::less)が使われるので定義しておかなければならない。 struct Set { int a; double b; Set(int i, double d) : a(i), b(d) {} }; bool operator>(const Set& a, const Set& b) { return a.b > b.b; } bool operator<(const Set& a, const Set& b) { return a.b < b.b; } int main() { std::multiset<Set, std::greater<Set> > ms, ms2; ms.insert(Set(1, 2.0)); ms.insert(Set(2, 1.0)); ms2.insert(Set(1, 0.0)); ms2.insert(Set(1, 0.5)); for (std::multiset<Set, std::greater<Set> >::const_iterator pos = ms.begin(); pos != ms.end(); ++pos) std::cout << pos->a << ' ' << pos->b << std::endl; if (ms > ms2) std::cout << "ms > ms2\n"; }
>>9-10 なるほど。
自作クラスSetに>を実装しないとstd::setやstd::multisetに入れられないのは理解できました。
ありがとうございます。
しかしご教示いただきたいのですが、最後の方の
if (ms > ms2)
このms>ms2の部分がtrueやfalseになるという決定はどういう基準で決まるということですか?
例えばms == ms2でしたら、「最初から最後まで全要素がmsとms2で等しい時true, 他はfalse」ですよね。
ms>ms2はどうなのでしょうか?
>>11 これで見る限り木の単純比較のように見えます
std::equal()を使っても同じ結果が得られると思います
struct Set {
int a;
double b;
Set(int i, double d) : a(i), b(d) {}
};
bool operator==(const Set& a, const Set& b) {
return a.b == b.b;
}
bool operator<(const Set& a, const Set& b) {
return a.b < b.b;
}
int main()
{
std::multiset<Set> ms, ms2;
ms.insert(Set(1, 2.0));
ms.insert(Set(2, 1.0));
ms2.insert(Set(1, 1.0));
ms2.insert(Set(3, 2.0));
if (ms == ms2)
std::cout << "ms == ms2\n";
}
あ、size()も見ているようですね size()が等しくかつ単純比較で大小を決めているようです 1,3,5 1,2,6 のような場合はどちらが大きくなるかと、辞書順、つまり 最初に見つかった違いで判断しているようです
うーんsize()も見ていないのか?そうなるとstd::lexicographical_compareと同じアルゴリズムか? struct Set { int a; double b; Set(int i, double d) : a(i), b(d) {} }; bool operator==(const Set& a, const Set& b) { return a.b == b.b; } bool operator<(const Set& a, const Set& b) { return a.b < b.b; } int main() { std::multiset<Set> ms, ms2; ms.insert(Set(1, 3.0)); ms.insert(Set(2, 1.0)); ms.insert(Set(2, 5.0)); ms2.insert(Set(1, 1.0)); ms2.insert(Set(3, 2.0)); ms2.insert(Set(3, 6.0)); ms2.insert(Set(3, 1.0)); if (ms > ms2) std::cout << "ms > ms2\n"; }
15 :
11 :2009/05/04(月) 22:47:18
>>14 謎ですよね。ありがとうございます。
今、決定打を探してみています。
14882:2003 23.1 Table 65 に Container に対する a < b の operational semantics として lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()) って書いてあるよ。
多分辞書順だと思うんだけどなあ 手持ちの書籍を読んでもなかなか SGIのホームページを見ると Lexicographical comparison. This is a global function, not a member function. とあるから間違いないと思いますが 規格書を読むと§23.1のTable65にやはり convertible to bool lexicographical_compare linear (a.begin(),a.end(),b.begin(),b.end()) pre: < is defined for values of T. < is a total ordering relation. とあります
かぶったゴメン という事で辞書順という事で決まり・・・みたいですね
多分順序が付いているということが大事で、その付け方はそんなに重要じゃないと思う setの入れ子とかが出来るように適当に全順序決めてるだけだろうから
20 :
11 :2009/05/04(月) 23:09:32
決定打ありがとうございます。 辞書順と言うことはすなわち Rule1:msとms2で「格納している最小の要素」が大きい方を大きいとする。 Rule2:最小の要素が等しい場合は、それを除いてもうRule1を適用する。 Rule3:Rule2により要素が無くなったら、無くなった方が小さいとする。 ということですね。なんか変な定義ですねぇ。。。 ですが ms.insert(Set(2, 1.0)); ms.insert(Set(1, 3.0)); ms.insert(Set(2, 5.0)); ms.insert(Set(2, 7.0)); と ms2.insert(Set(2, 1.0)); ms2.insert(Set(1, 3.0)); ms2.insert(Set(2, 5.0)); ms2.insert(Set(2, 7.0)); ms2.insert(Set(2, 9.0)); とではms<ms2になるらしいですしやっぱりこういうことですよね。 ありがとうございました。
>>20 std::lexicographical_compare()の動作の仕方を理解できればいいよ
22 :
11 :2009/05/04(月) 23:15:13
いや、そう変に考えなくても単に先頭から見て大きい方を大きいと見なすってだけですね。 setやmultisetが自動でソートされるから紛らわしいと感じるだけでした。
たまには頭のいい体操になるな
24 :
11 :2009/05/04(月) 23:34:18
25 :
デフォルトの名無しさん :2009/05/05(火) 01:07:29
質問です。 割と大きめの行列にSVD(特異値分解)したいので そういうライブラリを探しています。 それで、liboctave C++を使おうと思い以下のコードを試しに実行してみたのですが、 2x2程度の行列なら、1秒以内に完了するのですが、このコードだと15分たった現在も結果が返りません。 実際に演算にかけたい対象は、更に大きいものなので、これでは使い物にならないのですが・・・ こんなものなのでしょうか?また他に良いライブラリはないのでしょうか?確かSVDに関しては高速化の手法がいくつか考えられてたとおもうのですが・・・ Matrix m(5, 6); m(0,0) = 1; m(0,1) = 0; m(0,2) = 1; m(0,3) = 0; m(0,4) = 0; m(0,5) = 0; m(1,0) = 0; m(1,1) = 1; m(1,2) = 0; m(1,3) = 0; m(1,4) = 0; m(1,5) = 0; m(2,0) = 1; m(2,1) = 1; m(2,2) = 0; m(2,3) = 0; m(2,4) = 0; m(2,5) = 0; m(3,0) = 0; m(3,1) = 0; m(3,2) = 0; m(3,3) = 1; m(3,4) = 1; m(3,5) = 0; m(4,0) = 0; m(4,1) = 0; m(4,2) = 0; m(4,3) = 1; m(4,4) = 0; m(4,5) = 1; cout << "Original Matrix" << endl << m << endl; SVD svd(m); cout << "Left Singular Matrix" << endl << svd.left_singular_matrix() << endl; cout << "Singular Values" << endl << svd.singular_values() << endl; cout << "Right Singular Matrix" << endl << svd.right_singular_matrix() << endl; cout << "Recomposed Matrix" << endl << svd.left_singular_matrix()*Matrix(DiagMatrix(svd.singular_values()))*svd.right_singular_matrix() << endl;
>>25 ソースから作った?あと、ATLAS組み込んだ?
ATLASをgcc4&SSE4&マルチコア構成でmakeしてみて
liboctaveに組み込めばかなり高速化すると思う。
SVDの演算ならそんなもんだよ。
そんなに速度が欲しいなら、精度無視してNNを使った方法を取ったら?
std::map<std::string, Myclass> the_map; で、存在しないキーを指定してアクセスした時はそのキーが自動的に登録されそのキーに対応する値はその値の型のデフォルトコンストラクタによって初期化されると聞きました。 試したところ、たしかにthe_map["this key doesn't exist."]とするとその値はMyclass()で初期化されていました。 では std::map<std::string, int> the_map; だった場合も大丈夫なのでしょうか? g++ではthe_map["this key doesn't exist."]とするとその値はint()で初期化されて0になっているようですが、これは他の環境でも期待して良い物でしょうか?
intとかについては T() の結果がマチマチじゃなかったかねえ
>>28 はい、それですと、
int型のクラスで言うところのデフォルトコンストラクタ
により0で初期化してくれるのですか?
たとえばstd::string str;だとデフォルトコンストラクタにより""になりますけど
int i;だと初期化されませんよね。
・・・と思いましたが、そう言えばint()で0が返るんでしたね
失礼しました。
>>29-30 組み込み型でもT()で全て初期化してくれるんじゃなかったか?
誰か有識者plz
8.5あたりに書いてあるな イニシャライザが空の括弧(要するに()のこと)の場合はdefault-initializeされ、 PODに対してのdefault-initializeとはzero-initializeであって、 スカラー型に対してのzero-initializeとはその型での値0をセットすることである と決められてる だからint()は0初期化が保証されてると考えておk ちなみにint i;みたいなのは「イニシャライザなし」であって()で初期化する場合とは区別される イニシャライザなしの場合は非PODはdefault-initializeだが、PODの場合は不定値と決まっている
33 :
30 :2009/05/05(火) 11:07:19
>>32 理解出来ました!
ありがとうございました。
pimplのインターフェースクラスのメンバ関数の実装はどこに書くべき? 具体的には↓↓ pimplイディオムを使うことを想定してMyClassとMyClass_implを定義した。 class MyClass_impl; class MyClass { boost::shared_ptr<MyClass_impl> pimpl; public: int foo(); //以下略 }; ここで、MyClassのpublicメンバ関数int foo()からMyClass_implのメンバ関数int foo()を呼び出すように int MyClass::foo() {return pimpl->foo();} と定義しろと学んだんだが、これはどこに書くべきなの? 実装ファイル.cpp(MyClass_implの定義と実装が書かれている)に書くべきなのか、 それともMyClassクラスの定義されたヘッダファイル.hに書かないと意味ないの?
35 :
34 :2009/05/05(火) 11:44:16
ただしMyClassクラスの定義されたヘッダファイル.hは 変更されないように極力努めるが、 実装ファイル.cpp(MyClass_implの定義と実装が書かれている)が しょっちゅう変更される物として。 お願いします。
>>35 MyClass.cppでfooの実装とMyClassImpl.hをインクルードすれば済むんじゃね?
別にimplがクラスである必要はネエ、PODでもOKと考えれば判ること。 cpp内でPOD*をキャッチボールしたりコンストラクタが役立たずになったりして コンパイラの最適化お仕事の邪魔になるだろうけど
38 :
34 :2009/05/05(火) 14:53:46
ふむ、となると、 int MyClass::foo() {return pimpl->foo();} これはどこに書くといいのかい?
そもそもそれヘッダに書けるの? MyClass_implの定義は実装ファイル.cppに書かれてるんでしょ?
40 :
34 :2009/05/05(火) 15:26:33
>>39 あ・・・そもそもMyClass_implが不完全型だから
fooを持っているかどうか分からないから書けないのか。
ごごごごごごごめん
正直すまんかった。
>>37 ん?ClassとPlain Old Data、どっちで_implを実装すべきだというのだい?
興味あるからその辺の話を聞かせてほしい。
43 :
34 :2009/05/05(火) 15:35:27
>>41 pimplには実装の隠蔽という役割もあったか。
よし、本気で勉強してみるわ。thx
POD*を丸々投げ返す様なローカル関数が無けりゃどっちでも良いんじゃないかな
45 :
42 :2009/05/05(火) 15:46:08
>>44 ほう、特にどちらでもおk、と。
どうも。
46 :
42 :2009/05/05(火) 23:18:16
しかし中々興味深いな。 明確な解ではないとはいえ、私の情報論理構成の範疇外の事象とは。 おっと、言葉が過ぎたようだ。また組織から小言をもらってしまう。 では。
47 :
42 :2009/05/05(火) 23:28:50
48 :
42 :2009/05/06(水) 02:15:10
私はバカです。
49 :
42 :2009/05/06(水) 02:16:48
釣れた!
std::cout << HOGE << ':' << PIYO << std::endl; みたいに書く時って、 std::cout << HOGE << ":" << PIYO << std::endl; とどっちがいいの?
51 :
デフォルトの名無しさん :2009/05/06(水) 13:18:40
どちらでもお好きに。
1バイトのみの出力であれば、「NUL文字までループ」しない分、前者の方がわずかながら速いだろう。 しかし気にするほどではない。
考え方によっては":"が何回も出て来るなら、 同じ文字列をマージする最適化をコンパイラが行うとかは考えられない?
考えたくない
55 :
11 :2009/05/06(水) 14:19:35
また来てすみません
コンテナのa < b
lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())
sed::setの場合は格納している値を辞書式に比較すると言うことでしたが、
std::mapの場合はどうなるのでしょうか?
mapの格納している要素はkeyと値の組になっていますが
どちらで比較するのでしょうか?
サンプルソース
C++ code - 51 lines - codepad
ttp://codepad.org/XOdZ3Avt mymap<yourmapがtrueとなるのは
Rule1:mymapの最初のkey < yourmapの最初のkey の時。
Rule2:(mymapの最初のkey == yourmapの最初のkey) ならば (mymap[key]で得られる値 < yourmap[key]で得られる値) の時。
Rule3:最初のkeyも最初の値も同じなら、次の要素でRule1, Rule2を適用する。
Rule4:Rule3にてmymapの方がyourmapより先に次の要素が無くなった時。
といった感じがするのですが、ご存じの方いらっしゃいますか?
56 :
50 :2009/05/06(水) 14:20:47
57 :
デフォルトの名無しさん :2009/05/06(水) 14:25:31
VS2008をダウンロードして起動してみたのですが、 全くどう使っていいのかわかりません… 画像付きで解説してるサイトはありませんか? とりあえずハローワールドすら出来ないと泣きそうです VBAなら少しさわったことあります よろしくお願いします
59 :
デフォルトの名無しさん :2009/05/06(水) 14:29:25
60 :
デフォルトの名無しさん :2009/05/06(水) 14:33:21
>>58 おお、そんなスレがありましたか失礼しました
>>59 ありがとうございます!
61 :
11 :2009/05/06(水) 15:31:33
>>55 ・・・な〜んか違うよーな。
コンテナの比較って相変わらず分からないです。
>>61 あってんじゃね?俺も知らんけど、見た感じそうなってると思う。
その理解でいいだろ。 lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()) は対応するイテレータがそれぞれ参照している要素をoperator<で比較していく。 mapのイテレータが参照しているのはpair<key_type,mapped_type>。 pair<first_type,second_type> x,y に対して x < y が真になるのは x.first < y.first または !(y.first < x.first) && x.second < y.second が真になるとき。
>>63 × !(y.first < x.first) && x.second < y.second
○ y.first == x.first && x.second < y.second
65 :
64 :2009/05/06(水) 16:07:08
あ、pairって等価ベースだったか。すまん。
本を買って通勤中や暇な時間に勉強しようと思うのですが、 オススメはありますか? 上の方のレス見たらそんな本は捨てた方がいいとか書いてあって怖くなりました(間違った知識がつくんじゃないかと) とりあえず古本屋も見てみたのですが、10年ぐらい前のしかありませんでした…
67 :
デフォルトの名無しさん :2009/05/06(水) 17:56:43
やさしいC++ 第3版
ありがとー! さっそく買ってきます
レビューとか読んでからにしろよ。
教えてください、以下のプログラムでいい方法がないものかと。 またはC++的にはこう書いた方が正しい等です。 //------------------- class AA { int a1; }; //------------------- class BB { AA **app; void setapp(int no) { app = new (*AA)[no]; //<-ここが不明 エラーになる } }; //------------------- int _tmain(int argc, _TCHAR* argv[]) { BB dat; dat.setapp(10); } 1.<−−ここが不明の部分の書き方 2.こんなのは良くない、もっといい方法がある。 の2つです。お願いします。
71 :
11 :2009/05/06(水) 20:30:32
>>62-63 ありがとうございます。
最終的には、
>>55 の見解で良いとのことですが、
(pairが)等価ベースとはどういう事でしょうか?
>>70 エラーメッセージが読めるようになってからまたお越し下さい。
74 :
70 :2009/05/06(水) 20:43:33
error C2226: 構文エラー : 'AA' 型指定子の前あるいは内部で構文エラーが発生しました。 エラーメッセージは上記です。 正直わからないから聞いているので。 答えられないのであればあきらめます。
>>74 > 答えられないのであればあきらめます。
ああそうか、じゃあ俺の頭じゃ答えられないわ。
app = new AA*[no];
77 :
70 :2009/05/06(水) 20:52:41
>>76 出来ました、ありがとうございます。
所で、クラスの配列を動的に作ってアクセスする場合。
この様なポインターの配列をnewしてクラスデーターを入れて管理するのは。
ごく普通のやり方でしょうか? どうもなんか、いまいちなような気がして・・・
>>70 > 2.こんなのは良くない、もっといい方法がある。
強いて挙げると
newで得た配列はデフォルトコンストラクタでしか初期化されません。
ポインタの(と言いますか組み込み型の)配列となると全く初期化されませんけど大丈夫ですか?
ということと
setappがpublic:じゃいのでアクセスできませんよ。
ということと
忘れずにdeleteしてくださいね
ということと
もしかしたらnewで例外が発生するかもしれませんよ
ぐらいかな。
一応、std::vector を使うのがいいかなと思う。std::vector<AA*> って感じ。
これでも
>>78 の問題はほとんどそのままだが。
80 :
78 :2009/05/06(水) 20:58:23
>>77 そもそも
>>70 だとAAのインスタンスは一つも存在していないんだけど、
それは分かっている?分かっていない?
81 :
70 :2009/05/06(水) 21:00:59
public:忘れてました、すみません。 最終的に //------------------- class AA { int a1[10]; }; //------------------- class BB { public: AA **app; void setapp(int no) { app = new AA*[no]; //<-ここが不明 } }; //------------------- int _tmain(int argc, _TCHAR* argv[]) { BB dat; dat.setapp(3); dat.app[0] = new AA(); dat.app[1] = new AA(); dat.app[2] = new AA(); } こんな感じでうまくいったのですが、本当にこのままでいいのだろうかという疑問が・・・
82 :
70 :2009/05/06(水) 21:06:15
std::vector 使ったことないです、調べて見ます。ありがとうございます
あとはboost::ptr_vector<AA>とか
84 :
78 :2009/05/06(水) 21:10:22
>>81 > こんな感じでうまくいったのですが、本当にこのままでいいのだろうかという疑問が・・・
>>78 にあるとおり、良くない。
いつdeleteするかとか、newが4回あるうちのどこかで例外が発生しうるがその時はどうするかとかは?
たぶんboostないしstd::tr1のshared_ptrが必要になるのではないでしょうかね。
・・・ってstd::vector使ったこと無いのか。
じゃあまずSTLのお勉強だな。
STLの前にポインタの勉強からじゃ
構成上、どうしてもコンストラクタで例外を投げたいんだけど、 良いんだよね?別に。 そう言うこともあるよね?
某サイトで「コンストラクタで例外を投げるな」なんて書いた人がいたけど 基本的には問題ないし、コンストラクタで正常にオブジェクトの構築が出来ないときは 例外を投げるのが最も適切。 もし、気になっている問題があるなら、具体的に書いてもらってもいいけど。
88 :
デフォルトの名無しさん :2009/05/07(木) 00:05:27
>>71 > (pairが)等価ベースとはどういう事でしょうか?
その元レスは直前のレスに対する独り言のようなものだろうから文面をそのまま受け取っては駄目。
おそらく以下の説明のようなことを踏まえての発言。
pairのoperator<はまずfirst同士を比較して、それが等しければsecond同士を比較するという流れ。
ここで等しければを判定するのに等値かどうかで判定するのではなく等価かどうかで判定する。
>>86 後始末が必要なものをしっかりかたづけてればおk。
A(){
h = gethandle(); // 後で明示的に解放する必要あり
/* このあとに例外投げるかもしれない処理を行う */
}
~A(){
releasehandle(h);
}
みたいな場合、例外をコンストラクタの外に投げる前に後始末が必要。
「解放すべきもの(newで確保されたメモリや、その他のリソースなど)を保持してデストラクタで解放する」 という仕事をするためのクラスを利用すると、例外に対処しやすい。 そういうクラス自体の設計時は例外安全に注意する必要がある(コンストラクタでうかつに例外を投げてはならない) が、そういうクラスの利用者のほうは適当に例外を投げてもリソースリークが起こらないようになる。
日本語でおk
93 :
91 :2009/05/07(木) 01:02:48
>>92 は俺に言ってる?
例えばスマートポインタを使う場合が最も分かりやすい。
次のようなクラス MyClass があったとする。
class MyClass {
public:
MyClass();
~MyClass();
private:
MyAnotherClass* p;
};
で、MyClass::MyClass() の内部で p = new MyAnotherClass(); などとして、
MyClass::~MyClass() で delete p; しているとする。この場合、MyClass::MyClass() が迂闊に例外を
スローすると、MyClass::~MyClass() が実行されないためにpが解放されない場合があるから、
例外をスローする場合はpの解放がきちんとされるように、注意深くコードを書かなければならない。
ただし、メンバ変数 p をポインタではなくスマートポインタとすると、そのような注意は不要となる。
例えば std::auto_ptr<MyAnotherClass> p; となっていて、MyClass::MyClass() の内部で
p(new MyAnotherClass()); とした場合、たとえMyClass::MyClass()が例外をスローしても
newされたものはちゃんと解放されるから、神経質にならなくて済む。
忘れてはならないのは、スマートポインタのコンストラクタが迂闊に例外をスローしてしまうと、
結局、リソースリークの可能性は消えないということだ。まあ自分でスマートポインタを書いて使うことは
普通の人はないと思うけど、実際 boost::shared_ptr 等はコンストラクタで例外を投げる場合があり、
その場合でもリソースリークが起こらないようにちゃんと配慮されている。
94 :
91 :2009/05/07(木) 01:08:31
ごめん、std::auto_ptr 使って p(new MyAnotherClass()); は無いね。 コンストラクタのメンバ初期化子に書いたと思ってくれ。
>>91 「そういうクラス」「そういうクラスの利用者」って何?
「そういうクラスの利用者『のほう』」って何と比べてるの?
明らかじゃないから聞いてるんだろ。 明らかだと思うなら、どう明らかか書けばいい。
99 :
11 :2009/05/07(木) 11:35:51
>>89 等値(equality)
a == b
等価(equivalence)
!(a < b) && !(b < a)
これの事ですね。
ありがとうございました。
>>98 std::auto_ptr とか boost::shared_ptr とかが「そういうクラス」。
101 :
100 :2009/05/07(木) 11:37:50
まあクラスじゃなくてクラステンプレートか。 std::auto_ptr<MyAnotherClass> とかが「そういうクラス」だと思ってもらえれば。
102 :
86 :2009/05/07(木) 11:51:26
>>87-101 サンクス。
でかいクラスじゃなく、リソース漏れも起こすことはないハズのコーディングにしてあるので
大丈夫だ。どうも!
104 :
デフォルトの名無しさん :2009/05/09(土) 16:12:48
std::vector< std::pair< key_t, value_t > > v; for( std::vector< std::pair< key_t, value_t > >::iterator i = i.begin();.... というコードがあるとして、for文の「std::vector< std::pair< key_t, value_t > >」のように 長いテンプレート型書く必要が多々あり、それが面倒に感じます。 「v.self_type」のような、変数名から型を引っ張ってくるような 仕組みは出来ないものでしょうか?
typedef すれば?
次期規格でdecltypeというのが出来るが今は無理
typedef しとけ
decltype よりゃ auto じゃね
>>107 だからC++03ではtypmlateのtypedefは無理だっつーに
×typmlate ○template
>>110 部分特殊化のような形の typedef は無理だが
>>104 みたいなのは全く問題ないっつーか、常套手段だろ
>>110 パラメータが確定してるテンプレートクラスならできるぞ
できないのはtypedefのテンプレート
>>110 ・・・まさかやったこと無いわけじゃないよな?
typedef typename std::vector< std::pair< key_t, value_t > > hoge; 通りませんでしたよ^^ VC2008
typename要らない
釣り臭いな
>>115 using alias使うんだよ
using hoge = std::vector< std::pair< key_t, value_t > >;
素だろ また的外れてるし。
>通りませんでしたよ^^ これは釣りだろ
VC++の学習用にサブPCを導入しようと思うのですが、 atom330でも問題なさそうでしょうか あまりに重そうならE1400辺りで自作しようと思います
別に問題ないだろ IDE使いたいなら話は別だが
>>121 全く問題ないよ。
IDE使ったところで問題なんて起きないから大丈夫。
VC++2008EE使っていますが、 変数の値を常に表示する方法はありますか? 現在はcout<<hoge;みたいなものを随所に入れています VBにあったウォッチウィンドウみたいな奴が欲しいです・・
メニューの デバッグ|ウィンドウ|ウォッチ デバッグ|クイックウォッチ
>>124 無いわけ無い。
それともEEだと存在しないとか??
>>127 メニューにはデバッグ実行中でないと出てこないはず
というか、初期状態でデバッグ実行したら下に自動変数とかローカル変数のタブ出てこない?
確かに間違って閉じちゃうと探すのに苦労するね
ああ、出てきましたありがとう!!! コッソリタブが増えてました こりゃ気づきませんぜ・・
131 :
デフォルトの名無しさん :2009/05/10(日) 05:03:03
誰でもそりゃわかってりゃ気づくけどな。 普通はなかなか気づかないだろう。
VC6の時代から使ってる人なら「必ずあるはずだ」って必死に探すなw
有用なサービスほど消えることは無い、 無いよな、 しかし気がつくと、 いや、無いと言ってくれー
メニューから消えてるだけのこともある いくつかのショートカットキーとか
動的なハッシュテーブルを作っていて、[]演算子をオーバーロードしようと考えているんですが、 代入する時と参照する時とで挙動が完全に変わってしまいます。 C#のgetメソッドやsetメソッドのような完全な書き分けってどうやるんでしたっけ。
そういう書き分けは無いのでやるなら別関数にすれ 挙動が異なるなら、別の表記を取るのが一番間違いが無い
書き分けは無理 proxyクラスでも使え
const メンバ関数か非 const メンバ関数かという差で挙動を変える事はできるが、 それで大丈夫なものなのかは疑問だ
[] の戻り値をクラスにする方法もあるけど・・・ 個人的にはあまり好きではないな
141 :
136 :2009/05/10(日) 17:16:05
142 :
136 :2009/05/10(日) 17:16:58
演算子のオーバーロードはあまり乱用すべきものではないので 細かい技法を使わないと演算子のオーバーロードでは実現できないような処理は 普通のメンバ関数にしてしまった方がいいと個人的には思う
>代入する時と参照する時とで挙動が完全に変わってしまいます。 同じように見せたいのなら<map>みたいにすればいいと思うけど
std::cin >> hoge;で受け取れるような自作クラスMyClassのオペレータオーバーロードはどうすればよいのですか? std::cout << hoge;ならサンプルコードが良く見つかるのですが。。。
同じようにすりゃ良いじゃん
>>146 というのは、例えば
std::string str;
std::cin >> str;
としてstrから適切に処理すれば良いってことですか?
std::complex<> を参考にしろよ (n,m) の形式で読み取るが、どのようにして実現しているのか 考えるのも楽しいものだ
istream &operator >>( istream&, const MyClass& );
150 :
147 :2009/05/10(日) 19:52:38
>>148 ありがとうございます。
さっそく見てみます。
>>149 ありがとうございます。
宣言の方は
std::ostream& operator << 〜
で理解しました。
C++ code - 31 lines - codepad
ttp://codepad.org/YWNCgmUO このソースはgccに付いてきた
std::complex<〜>のstd::istream& operator>>(std::istream&,complex&);のソースなのですが、
この
if (__ch == ')')
__x = complex<_Tp>(__re_x, __im_x);
else
__is.setstate(ios_base::failbit);
が何をしているのか分かりません。
自分なりに推測するとstd::istreamで読み込んでいった結果、所定のフォーマットになっていない(閉じ括弧がおかしい)場合にエラーを伝えるべくsetstateとやらをしているようなのですが、
__is.setstate(ios_base::failbit);
ってどういう意味ないし効力なのでしょうか?
std::ios::failbit が立つと、それ以降の入力は一切行われなくなる これがCとは違う所 この状態をクリアするにはis.clear()を行う
153 :
151 :2009/05/10(日) 22:02:27
>>152 フラグ立てですか。
読み込みに失敗したと言うことで、エラー状態にしているわけですね。
ありがとうございます。
・・・でも何で例外を投げる仕様にしなかったのでしょう?
使いづらそうな。。。
C++の本ってみんな今何読んでる?
今は何も読んでない
>>153 例外を投げる事もできる
ただ歴史的経緯があって例外がC++に存在しなかった時代から
iostreamは使われて来ているわけでデフォルトで例外はOFFに
されている
例外を投げるにはメンバ関数exceptions()にトリガとなるビットを
セットすればよい
157 :
153 :2009/05/10(日) 22:14:28
>>154 Boost C++ libraries 第二版
>>154 はじめてのC。
電車の中で立ち読みして
JKやOLからの冷たい視線でたまらなく興奮する人にお勧め。
>>154 やさしいC++
電車の中で読む度胸はないぜ
配列に配列を代入したいときは、 配列1[i]=配列2[i]などとしてforで回すのが一般的でしょうか
C++なら<algorithm>のcopy関数を使う方が一般的
memc(ry
つ std::copy 一見関数だらけになるが、恐ろしいほど最適化される。
>>154 Programming - Principles and Practice Using C++
std::vector<char> v(256); で &v[0] を char 256個の配列として扱って良いものですか?
>>167 ええよ
C++98とC++03間の変更点の一つにvectorはリニアアドレス↑に
取られる事が保証されたというのがある
規格票を見れば書いてあるはず
stringはまだでc++0xで保証される予定
GUIを考えています。 例えば、ボタンの上にマウスを持っていった時に、ヘルプメッセージを出す事を考えます。 所謂コマンドパターンによる実装になると思うのですが、 ボタンが親子関係でもないオブジェクトの参照を持つ事になり、気持ち悪く感じます。 これは気にしても仕方ない事なのでしょうか?
仕方ないというより、別に気持ち悪くないし。
履歴一覧を表示する元に戻すボタンでも実装するのか? >所謂コマンドパターン って言ってみたかっただけなんじゃ
173 :
167 :2009/05/13(水) 21:17:48
>>168 , 169
ありがとうございます。
std::string の c_str() のようにポインタを取得するというメソッドが
無いので、もしかしてやっちゃいけないことなのかと不安に思ったのです。
C/C++の趣味グラマなんだけど、 アセンブラも勉強した方がいいのかな?
わざわざしなくていいと思うよ 意識せずとも、いずれ自然に必要になって自然に勉強してる
176 :
174 :2009/05/13(水) 21:52:03
>>175 ほほう、そんなもんなのか。ありがとう。
むしろもうちょっと高級言語も知っとこうかなぁ。。。
C/C++をやると平気でインラインアセンブラを書くようになるよな 特にSSE2/SSE3関連は
>>171 ,172
クラスの関連が複雑になるのと、オブジェクトの寿命管理の点が気になりました。
> 履歴一覧を表示する元に戻すボタンでも実装するのか?
これも1つです。
ソースの見通しが悪くなり、あとで機能を追加したいと思った時に困るのではないかと思いました。
ササビーってIntelから出るけどあれどうなの?
俺、趣味でオセロプログラム書いてるけど、
>>177 みたいなことに手を出してみた。
最初は難しいイメージがあったが、やってみるとそうでもなかった。
181 :
デフォルトの名無しさん :2009/05/14(木) 02:25:47
0から1の乱数を表示させるプログラムがほしいんですがわかる人いますか? 調べてみてはいるのですが、なかなかうまく動きません。 乱数生成のためのソフトとかはいるのでしょうか? もしお暇がありましたらよろしくおねがいします。
>>181 今、どれくらいの知識を持ってるの? どんなコード書いてみたの?
とりあえず、標準Cライブラリの rand っていう関数は知ってる?
double r; srand((unsigned int)time(0)); r = rand() / RAND_MAX; printf("%lf", r);
static_cast<double>(rand()) / RAND_MAX;だろとツッコミがほしいんだろ
>>183 きっと0か1しか返さないぞ。
>>178 >ボタンが親子関係でもないオブジェクトの参照を持つ
ここでいってるオブジェクトってコマンドクラスのこと?
同じボタンの機能がころころ変化するのでもなければ
参照を持つ必要なんて無いと思うけど?
どうしてもUIにヘルプ文字列を埋め込みたくないのなら
コントロールクラスに自分(ボタン)が今どんな機能なのか
問い合わせるメソッドでも作ったら?
186 :
デフォルトの名無しさん :2009/05/14(木) 03:34:01
>>182 rand関数はさっきから学びはじめたばかりです。
知識は基本的なプログラムならつくれる程度です。
randは本格用途では使い物にならんぞ ゲームのサイコロ振るくらいに使うならいいけど
>>186 rand関数は、0 から RAND_MAX までの範囲の整数を返す。
(RAND_MAX は実際にはある特定の数値であり、コード中に RAND_MAX と書けばその数値として扱われる)
後は、0 から RAND_MAX までの範囲の整数を、0 から 1 までの間の小数の値に変換すればよい。
>>183-185 あたりを参考に。まだ分からんところがあったら聞いてくれ。
もし本格的な乱数を使用したいなら、boostのrandomってのを調べてみるといいが、
まあそこまでする気がないならrandでいいよ。
189 :
デフォルトの名無しさん :2009/05/14(木) 03:43:14
>>187 本格用途ではなくごく簡単なプログラムで、サイコロを振る程度です。
>>188 rand関数について自分でも調べていたところです。
丁寧におしえていただきありがとうございます。
もしわからないことがあったら書き込みたいと思います。
ありがとうございました!
190 :
189 :2009/05/14(木) 04:34:11
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { double random; srand((unsigned) time(NULL)); // rand関数による乱数生成を不規則にする for(int i=0; i<20; i++){ random = (double)rand()/RAND_MAX; // 0から1までの乱数の生成 printf("%f\n",random); // 表示する } } ここでのアドバイスなどをもとにして自分でつくりました。 コメントは自分でつけたので語弊があるかもしれません。
191 :
189 :2009/05/14(木) 05:08:06
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { double random; srand((unsigned) time(NULL)); // rand関数による乱数生成を不規則にする for(int i=0; i<20; i++){ random = (double)rand()/RAND_MAX; // 0から1までの乱数の生成 printf("%f\n",random); // 表示する } } ここでのアドバイスなどをもとにして自分でつくりました。 コメントは自分でつけたので語弊があるかもしれません。
192 :
189 :2009/05/14(木) 05:11:06
すみません一つはまちがいです。 上のプログラムだと乱数表示はされるのですが 一個だけ乱数表示するプログラムを実行すると、何度実行してもほとんど変わらない乱数 (例えば、0.963742 ⇒0.972378 ⇒0.981201など) になってしまいます。 良い解決方法はないでしょうか?
win32環境ならtime()をGetTickCount()なりQueryPerformanceCounter()なりで置き換えるとか。
>>185 > ここでいってるオブジェクトってコマンドクラスのこと?
> 同じボタンの機能がころころ変化するのでもなければ
> 参照を持つ必要なんて無いと思うけど?
ヘルプメッセージを表示するクラスのメンバ関数をboost::functionに入れてボタンクラスに渡すという意味です。
Clickなど他のイベントも同様に「他のクラスのメンバ関数をboost::functionに入れて〜」とやっていったらクラスの関連が複雑になるのではないのかと。
また、boost::functionの中で保持されているポインタの寿命(有効か)の不安を感じます。
random = (double)rand()/(RAND_MAX+1.0); // に、しとけ。
struct A{virtual void operator()()=0;}; struct B:A{virtual int operator()(int)=0;}; struct C{A&x;C(A&a):x(a){} int operator()(int i){return static_cast<B&>(x)(i);}}; struct D:A{void operator()(){}} d; int f(){ C c(d); c(); return c(1u); // これ・・・ } コンパイルを通ってしまわない様にするにはどう改造すればいいのでしょう?
>>196 コンパイルが通らないようにする方法ならいくらでもわるわけで、
何がしたいのか挙げてもらわないと望む答えは得られないでしょう。
198 :
196 :2009/05/14(木) 08:10:12
void operator()(){x();} を書き忘れ struct C{A&x;C(A&a):x(a){} int operator()(int i){return static_cast<B&>(x)(i);} void operator()(){x();}};
>>199 結果に整数 N をかけることで、簡単に N とおりの選択に使う乱数が得られる。
「0 から 1 の乱数」が 1.0 を含んでいると、こうはいかない。
>>200 今回の目的は
「0から1の乱数を表示させる」
だけど、いいの?
>>201 日本語だけでは閉区間なのか開区間なのか、区別がつかないんで、
質問者に判別してもらうしかないな。
簡単なサイコロの用途であれば 200 の性質が役に立つはずなんだけど。
簡単なサイコロの用途であれば、 random = rand()%6; // で、十分。
204 :
189 :2009/05/14(木) 11:12:04
>>193 「GetTickCount()識別子が見つかりませんでした」とでます。
変数として扱われているのですかね・・・
他のプログラムをみてみたのですが使い方がわかりません
勉強不足ですよねスミマセン
>>195 お返事ありがとうございます
プログラムの下から4行目のことですよね?
してみたのですがほとんど値がかわりませんでした
何かまちがっているでしょうか
205 :
189 :2009/05/14(木) 11:13:50
>>193 「GetTickCount()識別子が見つかりませんでした」とでます。
変数として扱われているのですかね・・・
他のプログラムをみてみたのですが使い方がわかりません
勉強不足ですよねスミマセン
>>195 お返事ありがとうございます
プログラムの下から4行目のことですよね?
してみたのですがほとんど値がかわりませんでした
何かまちがっているでしょうか
206 :
189 :2009/05/14(木) 12:43:26
>>193 GetTickCount()は識別子が定義されてませんとでてしまいます
変数としてあつかわれてしまっているようです
>>195 お返事ありがとうございます
1を足したのですがあまり乱数はかわらなかったのですが
何かまちがっているのでしょうか
207 :
195 :2009/05/14(木) 12:45:45
コンパイラは Borland だろ。
208 :
189 :2009/05/14(木) 12:49:10
>>193 GetTickCount()は識別子が定義されてませんとでてしまいます
変数としてあつかわれてしまっているようです
>>195 お返事ありがとうございます
1を足したのですがあまり乱数はかわらなかったのですが
何かまちがっているのでしょうか
209 :
189 :2009/05/14(木) 12:51:07
すみません何度もかきこんでしまいました
210 :
189 :2009/05/14(木) 12:55:04
>>202 [0,1)区間となっています。0以上1未満ということです。
サイコロの乱数程度といってしまいましたが
サイコロは関係ありません
>>208 windows.hをインクルードしてないとか言うなよ
だって、それを書けなんて誰も言ってないじゃないですか。
213 :
189 :2009/05/14(木) 13:30:44
>>211 ご指摘ありがとうございます。
してませんでした。
214 :
195 :2009/05/14(木) 13:41:16
すごく初歩的な質問ですが、C++で数字の小数点以下を 繰り上げるには何をつけたらいいんですか?
std::ceil()だろ Cにもある
つceil
それは「切り上げ」じゃん。ちゃんと答えてやれよ 因みに俺は小数点以下の「繰り上げ」なる概念について知らないので答えられん
くだらねえ…
220 :
215 :2009/05/15(金) 00:21:12
おかげさまで解決しました。どうもありがとうございましたm(_ _)m
ちなみにceil()は負の数は0から離れる方向になるからな
RAND_MAXが極端に小さい環境ならね。 32767程度あれば、5461回が5462回になる程度のばらつきだよ。
224 :
デフォルトの名無しさん :2009/05/15(金) 10:22:09
マジで⁉
線型合同法は下位ビットの周期性が
227 :
デフォルトの名無しさん :2009/05/15(金) 12:14:07
テンプレートのテクニックをまとめた、テンプレートの著書を教えてください。 知っているのは、modern C++ と、テンプレートテクニックという本です。 良いサイトや良い本の情報ください。
C++ Template Metaprogramming: Concepts, Tools, And Techniques From Boost And Beyond
マウスでいまクリック、もしくはドラッグしているファイルやディレクトリのパスを 取得する方法ってありますか?常駐ソフトのような形で、起動してからクリック、ドラッグ したファイルのパスをテキストログとして、出力するようなものを作りたいのですが・・・。
なんでこっちに来たんですか?
>>226 そんな乱数でもない数列をrand()という名前の関数の出力にする処理系が悪い。
ゴミだから早急に廃棄しろ。
>>225 製作工程の都合で、1,6の面積が微妙に大きいという話しか?
それとも、くりぬかれた目による重心のずれ、密度の偏りの方か?
233 :
デフォルトの名無しさん :2009/05/15(金) 13:55:52
>>228 ありがとうございます。
翻訳出てないんですかね……残念です。
C++の一番の特徴であるテンプレート関係の本が少ないのは何故?
わかりやすくテクニックを知りたいのに
234 :
デフォルトの名無しさん :2009/05/15(金) 15:54:15
すみませぬ JAVAから入っていまC++を勉強し始めたのですが、 C++で、配列で宣言した変数は、跡になってから自らがいくつの要素を持つ配列なのかチェックする方法ってありますか? Javaだと、 String str[] = new String[3] のように宣言した場合、 str.length を見れば要素数を見ることができますが、C++の場合は方法ありますか?
>>234 ないから素直にstd::vector使っとけ
>>234 sizeof(str) / sizeof(str[0]) で自分は調べてる
大丈夫、話が噛み合ってないだけだ。 char * foo = new char[3]; した場合は要素数を知る手段はない。 char foo[] = "abc"; した場合は要素数(≠文字数)を>236で得られる。
240 :
234 :2009/05/15(金) 16:20:29
ありがとうございます。 C言語の場合、 配列を作ったら作りっぱなし、メモリのどこまでがその配列に割り当てられた場所かという情報はどこにもないという認識で良いですか? たとえば10要素の配列を作ったあとに20番目の要素にアクセスしようとすると、JAVAだとぬるぽが出て教えてくれますが、 Cの場合はシステムから見てそれが分からずに、20番(に相当する場所)を読みに行ったり、書き込んでしまう という理解で良いですか?
良いです。 ちなみにここはC++のスレです。
>>240 そうです
運が良ければアプリ自体が吹っ飛んでくれますが運が悪いとそのままメモリ破壊して動き続けます
なのでJavaしかできない人が集まってC++案件とかやるととても楽しいことになります
そもそも、10要素の配列を作ったあとに20番目の要素にアクセスしようとするような奴は 「Javaしかできない人」ではなく、「Javaもできない人」
>>240 大きな勘違いをしている。
>配列を作ったら作りっぱなし、メモリのどこまでがその配列に割り当てられた場所かという情報はどこにもないという認識で良いですか?
配列は、>36でサイズを得ることができる。
つまり、newなんていう外道なモノを使わずに、(昔なつかしの)固定長配列を使うかstd::vectorを使えと言うことだ。
Cに配列なんてなかった
何の話?
ついに狂ったか?
Cなんてなかった
コンピュータなんてなかった
平行世界とつながったな
仕事なんてなかった
ISOのC++の2003年の規格のJISは訳がひどいですね。 原文の構成もひどいけど。 規格をもっと読みやすくしたような、同じだけ詳しい本ってあるんでしょうか?
無いから我慢して読め
規格書の文章なんてどれもああいうもんだよ。 訳が酷いわけじゃない。
C++は規格自体がひどいから文章もひどくなる
C++の文法があまりに酷いもんで翻訳者もイライラしながら 訳してたんじゃないか?w
どのくらいメモリを使っているかという情報は型が持っているのだから 例えば、char[3] 型の最初の要素のアドレスをchar*型に代入したら もうメモリサイズがわからなくなるのは当然といえば当然。 char[3] 型を char[3] 型に代入する分にはちゃんとサイズがわかる。 という感じかしら
変数の型も含めてすべてをクラスにってのがJava以降に導入されたもんだからね
それは別にJavaで初めてというわけじゃないだろ。
Javaも全てがクラスというわけでもないし。
全てがクラスになる unlambdaやれば全てが関数だからオススメ。
C++の一行の文字数って標準仕様上、制限ありますか? またあるとして、現実的に気にした方が良いですか?
メモリの許す限りという制限すらない無制限
ありがとうございます。 じゃあ気にせず行きます!
80文字が一つの目安だな。 120文字超えてたらちょっとイラッとする。
クラスのメンバ関数の返り値は コピー返しでも可能ならconstにしろ とEffective C++で言われていましたが、 なぜか返り値がbool型だけはconst付けない風習がありません? 例: bool is_valid() const {return member?true:false;} この場合も返り値にconst付けた方が良いのでしょうか?
269 :
デフォルトの名無しさん :2009/05/17(日) 11:34:17
付けた方がいいよ。
271 :
268 :2009/05/17(日) 11:58:07
>>269 そうですよね。ありがとうございます。
>>270 組み込み型の返り値を万が一変更するバカが居た場合の予防です。
>組み込み型の返り値を万が一変更する なんてできません。 馬鹿って言う人が馬鹿なんだぞw ちゃんと読もうぜ。
メリットは記述の統一感かな? テンプレート引数にするときにいいことってある? 自分は組み込み型にはconst付けない派だな
それ書いてあるのってEffecitve C++だっけ? Exceptionalかなんかのほうだった気がするが。
> テンプレート引数にするときにいいことってある? 全くない。 むしろ 組み込み型戻り値のconstは 環境によってはwarningやerrorになるから うっとうしいことこの上ない。
constな自クラス型参照メンバなんか使いだすと有りとあらゆる宣言にconstが波及して`err passing〜'の楽しい事になるんだよね。
277 :
271 :2009/05/17(日) 13:06:18
>>272 > >組み込み型の返り値を万が一変更する
> なんてできません。
有名どころのコンパイラならちゃんとコンパイルエラー出してくれるみたいですが
環境が違っても確実に予防してくれるのでしょうかね?
>>274 Exceptional C++だったかもしれません。
>>275 gccやboostの実装でも確かに組み込み型の戻り値にconstは付いていないようですね。
そもそも「組み込み型の返り値を万が一変更する」って どういう意味なの?
public継承は分かる。 private継承も分かる。 ではprotected継承は? 使ったことある人います?(遊びじゃなく実用で。)
だからちゃんと嫁ってば。 Effecitve C++ 2ndの21節と29節に書いてあるのは、 非組み込み型のコピーを返す関数を左辺値として使われないように、 左辺値になり得る型が戻り値の場合はconst付けよーねってことと、 const宣言したメソッドがデータのハンドル(stringクラスのcharポインタとか)を 返却するときは戻り値にconst付けよーねってこと。 わざわざ押し入れからEffectiveC++取り出してきた俺に プッチンプリン買ってこいw >環境が違っても確実に予防してくれるのでしょうかね? ぶっ壊れたコンパイラの話をされても困る。
じゃあ俺はなめらかプリンでよろしく
282 :
271 :2009/05/17(日) 14:33:58
>>280 サーセン。吊って来ます。
ありがとうございました。
constの同音異義語っぷりもなかなか見事なものだ
>>280 非組み込み型の戻り値について const つけてあると、右辺値参照として取れなくなっちゃいそう。
この指針は将来的に非推奨になるんじゃなかろうか?
そもそも右辺値参照自体が、 Effective C++で問題が広く知れ渡ったことで 実装されることになったんじゃないかな。 ぷらぷら界に多大な影響を与えた引き替えに、 次の版は全面改定だな。
286 :
デフォルトの名無しさん :2009/05/17(日) 17:55:23
cppunitに関する質問ってありですか?
互換性考えたら右辺const値のオブジェクト代入は右辺値参照を無視してコピー噛ますんじゃないかな
そう。だから右辺値参照を使って最適化しているつもりが、うっかり今までどおりの コピーになったりすることが考えられる。まぁ最適化の範疇と認識する分には問題には ならないんだろうけど。
右辺値参照って、なんだかよく分からない。 C++0xが出れば解説も増えるかな?
僕もよく解らないけど、関数の返すオブジェクトがコピーされるとき、 もとのオブジェクトが捨てられる場面で、 コピーコンストラクタを呼ばないでよりコストの低い破壊的なコピー、 つまりオブジェクトのメンバを移動することをするってことなんでしょ? ただそれだけでしょ?
292 :
290 :2009/05/17(日) 21:12:34
そうそう、「移動」の概念(ムーブセマンティクス)を容易に実現するための言語仕様として考え出されたのが右辺値参照。 ほかに分かりやすい例を挙げるとしたらauto_ptr(の後継)がvectorに入れられるようになることとか、 functionやbindなどで各引数のconstや参照の有無の挙動を完全に再現したoperator ()を実現できるなんて効果がある。
多次元配列の要素全てを任意の値で埋めたい場合 どう書くのが良いでしょうか。 1次元の場合は std::fill や std::fill_n が使えるのですが。 int a[10][10]; for(int i=0; i < 10; i++) for(int j=0; j < 10; j++) a[i][j] = 42; ということをしたいわけです。
>>292 最初の例や2番目のコピーコンストラクタ・代入演算子が呼ばれる例でもムーブセマンティクスは効く。
そこのコピーコンストラクタ・代入演算子の呼出が、ムーブコンストラクタ・代入演算子の呼出になる。
一般にムーブコンストラクタ代入演算子はコピーコンストラクタと違って、
それより遙かに低コストで例外の投げようもない実装になるので、より最適なコードになるとされる。
>>294 自分で書いてるじゃねーか。何が不満なの?
297 :
デフォルトの名無しさん :2009/05/17(日) 21:34:04
酒鬼薔薇
298 :
290 :2009/05/17(日) 21:34:39
>>295 ほっほー。
そうなのかぁ。
ありがとう。C++0xが楽しみになって来たんだぜ。
いや普通に memset(a, 42, 100); で、いいんでない。string.h が使える環境なら それより最近、スザンヌとギャル曽根の区別が付かなくて困ってます 見分け方を教えてください
>>299 int に memset() して 42 になるとでも思ってんのか?
301 :
299 :2009/05/17(日) 21:47:53
303 :
299 :2009/05/17(日) 21:52:38
すまん。レス取り消し。int だったね 回線切って(ry
304 :
299 :2009/05/17(日) 21:53:52
>>294 その配列だったら連続性が保証されてるから
std::fill_n(&a[0][0], 100, 42)
でいいだろ。
>>294 お好きなほうをどうぞ。
std::fill_n(&a[0][0], sizeof a / sizeof a[0][0], 42);
namespace bll = boost::bind;
std::for_each(a, a + sizeof a / sizeof a[0], bll::bind(std::fill_n<int*, std::size_t, int>, bll::_1, sizeof a[0] / sizeof a[0][0], 42));
>>307 std::fill_n(first, n, val) は [first, first + n) に対しての操作だから
要素数でOK。sizeof a / sizeof a[0][0] は冗長。
それも要素数・・・
g++にてテンプレートに暗黙の型変換を絡めたら分からなくなったので教えてください。
C++ code - 60 lines - codepad
ttp://codepad.org/l7pocEaw このソースコードでは50行目hoge < short(1)の部分で
error: no match for 'operator<' in 'hoge < 1'
と言われてしまいます。どうやら暗黙の型変換がうまくいかないようです。
これを改変してForward declarationを無くして代わりにクラステンプレートの内部で friend 関数を定義することで回避できます。
C++ code - 49 lines - codepad
ttp://codepad.org/F0VomJTk しかし、どうして前者のソースコードでは暗黙の型変換がうまくいかないのでしょうか?
311 :
294 :2009/05/17(日) 22:30:18
みなさまありがとうございます。 std::fill_n(&a[0][0], sizeof a / sizeof a[0][0], 42) がよさそうですね。勉強になりました。
>>309 だから、要素数が既知なのに一々冗長に書くことないってこと。
>>312 「要素数が既知」ということに依存したコードにするほうが面倒なこともあると覚えておけ。
一般的には、保守性のほうが一回だけの記述の利便よりも重要だ。
>>313 何頭に血を登らせてるの?
質問者が提示したコードで要素数が定数になってたんだからそれでいいだろ。
不明な場合に要素数を計算するのは当然のこと。
>>312 マジックナンバーは避けるべきだろjk
const N = 10;
int a[N][N];
なんてしているならsizeofを使わずにNと書いてもいいとは思うけど。
そういう本質でない話はもういい
template<T,U>void fill(T (&d)[U],T v){for(unsigned i=0;i<U;++i)d[i]=v;} template<T,U0,U1>void fill(T (&d)[U0][U1],T v){for(unsigned i=0;i<U0;++i)for(unsigned j=0;j<U1;++j)d[i][j]=v;} マジックナンバーイラズサイテキ化キタイダイ int a[10][10]; double b[10]; fill(a,0); fill(b,0.0);
オナニーレスうぜえな ループを書きたくないってのが本題なのに、それじゃ本末転倒だろうが
>>318 何いってんの?
ライブラリって知ってる?
>>310 暗黙の型変換はテンプレートを具象化しなければならない時には行われないから
んで、どうすればいいかというと後者のようにすればいい
Effective C++の46項に詳しく書いてあるよ
>>284 ,285,288,289
C++0x の話としては,戻り値の型が const 修飾されていると
move 出来ない (immutable な右辺値になる) ので,
Effective C++ の記述がやや古くなるのはその通りだと思います.
C++0x 的には, EC++ のこの記述は
恐らく "Extending move semantics to *this" と
"Defaulted and Deleted Functions" との組み合わせに置き換わるべき話だと思います.
C++が苦手なCプログラマなのですが、ちょっと質問です。 ファイル内の文字列を探すプログラムです。 これをC++で書くとしたらこの程度でもクラスを作るのですか? #include <stdio.h> #include <string.h> int main(int ac, char * av[]) { //ファイルからメモリーに読み込み FILE * fp = fopen("文字列が入ったファイル", "r"); fseek(fp, 0, SEEK_END); int fSize = ftell(fp); fseek(fp, 0, SEEK_SET); char * buf = (char *)malloc(fSize); fread(buf, 1, fSize, fp); fclose(fp); //さがす char ss = "abcde"; int ss_len = strlen(ss); char * p = buf; for (int i = 0; i < fSize - ss_len; i++) { if (strncmp(ss, p, ss_len) == 0) { printf("%d番目に見つかりましたよ\n", i); return 0; } p++; } free(buf); return 0; }
おれはc++のOOP が標準だから、特別な理由が無い限りOOPで書く。 英語で育った人は、特に何も考えずに英語会話するのと同じ
その程度だと、既存のクラスを使うだけで出来上がるね。つまり、クラスを作る出番ではないと。 極論すればクラスってのは作るものというより使うもの。
それに、mallocをfreeしてないでしょ、終われば開放するけど、 それはたまたま短いプログラムだから、OOPだと、明示的にディストラクタがある。 まあ使わなきゃ意味無いけど、私はこれも標準で書いてしまう。だから少し安心なわけ。 それに、そのプログラムはバッファーオーバランしないようだけど、それも、保護されやすい。 ただし、標準でOOPが身についてるからであって、人によってはOOPでもいくらでも汚くかける。
あ、ごめ freeしてた orz
いや…、Cはもう、身についてないから…と言い訳する orz orz orz
一人で無駄に4レスも使いやがって
俺はその程度ならclass内でやったりしないな。FILEも普通に使うし。 ただ、バッファはvector<char>で確保するし 探索も文字列探索クラス(BM法とか)を作って実行するね。 処理自体は(mainには限らないが)普通の関数に置く。 ただこれは当然「ファイル内の文字列探索が処理の全て」の場合。 何らかのclassの処理の中でファイル内探索を必要とする時は、当然そのように書く。
330 :
310 :2009/05/18(月) 05:52:46
>>320 Effective C++では後者の方式が天下りに与えられていました。
あくまで前者のような方式(実装をクラス宣言部分に書かない)
で解決する方法はありませんか?
(後者の方式でprivate宣言されたヘルパー関数を呼び出すという回避策もありますけれど。)
>>325 destructor
はディストラクタではなくデストラクタね。発音的にも用語的にも。
ディスクトップでなくデスクトップなのと同じで。
>>330 関数が2つになっちゃうけど、
クラス内に
template<typename T> friend bool operator <(const Hoge &lhs, T rhs);
template<typename T> friend bool operator <(T lhs, const Hoge &rhs);
って書けば、関数テンプレートの定義を外に書けると思う…たぶん
それか、関数テンプレートをやめて定義を特殊化して書いてもいけるんじゃないかな。
間違ってたらサーセン
>>322 を見て思ったんですが、
ファイルを読み込み文字列検索するだけでこんな長く分り難いにコードにえーって感じなんですが、
C++を使って書くとこれより短く解りやすいコードになるんですか?
それはどんな感じになるんですか?
>>322 で
printf("%d番目に見つかりましたよ\n", i);
return 0;
ここでreturnしているんですが、ここではfreeしなくて良いんですか?
>333 main() {system("grep abcde 文字列が入ったファイル");} >free リークしていないので問題ないが、姑に目を付けられる。
でも突然サブルーチンに昇格する可能性もあるから、 常にfreeした方がいいよ。
>>334 >free
見つかった時、見つからない時の両方でfreeしないなら良いけど
片方しかしてないって、C使いらしくないんじゃない?
短いコードでたった2箇所を管理するだけなのに、それすら出来ないなんて
freeの仕様について言及しただけで、
>>322 のソース自体に文句付けるなら
もっといろいろあるだろ。
return 0; を break; に置き換えるとか?
ファイルを一気に読むのが好きになれない、俺なら1行ずつの処理にする。
配列まではすんなり頭に入ったけど、ポインタとかクラスのメンバ関数とかわけわかんねー・・ なんにしても作りたい物が無ければ頭に入らない気がしてきたんだけど、ドリルみたいなものって無いですか
宿題スレに山ほど
こんなスレあったのか、ありがとう
>>341 宿題スレはいいよな
糞問ばっかりだけど最初のうちは数こなす方が大事だし
344 :
310 :2009/05/18(月) 23:20:37
次はコナン風で頼む。
346 :
デフォルトの名無しさん :2009/05/18(月) 23:32:24
どっちのコナンだよ
やってくれるのか? わくわく
コナン・ザ・グレート風で頼む。
クラス中の宣言の中でメンバ関数の定義をした場合、 自動的にinline展開要請になるんだよね? では クラス中の宣言の中でfriend関数の定義を記述した場合、 inline展開要請になるのかい?
^^
inline展開陳情のほうがいいかも。
俺のBCC 6.1.0ではオプションを付けない限り inline は全部無視される\(^o^)/ デバッグの時の事を考えてだと
>>355 規格での項番まで示していただきまして、有難う御座います。
15.2/2 の箇所ですね。
規格に正しく準拠した処理系であれば問題ないとことで、懸念なく利用したいと思います。
有難うございました。
初心者ではないと思っていたのですが、初心者からこんな質問を受けて 的確に答えられなかった自分が恥ずかしいです。どなたか、模範解答を教えてください。 「ヘッダファイルの用途と、使用によるメリットは理解できました。 ただ、cpp ファイルを分ける目的がわかりません。 また、cpp ファイルを複数持たせた場合、ビルド順はどうなるのですか?」 宜しくお願いします。
むしろcppファイルを分けないでどうやってまともに開発しているのか分からないぐらいだが。 分割コンパイルすることで仕様変更に伴う再コンパイル時間の短縮とかも見込めるけど、 それ以上にそもそも他人が作ったクラスとかを使いたい(再利用したい)場合とか cppファイルが分かれてなかったら再利用できないだろ。
>>358 その観点で考えると、うちのプロジェクトは基本的にほどんどがヘッダファイルで構成されていて、
クラスは基本的に .h で作って #include で取り込む、っていう方法を取っています。
なので、再利用には困りません。
ほとんどがヘッダっていう考え方がNG?
あと、ビルド順序はどうなるものですか?やってみたんですが分かりませんでした。
いやまて。ヘッダファイルに直接定義を書き込んでいるのか? そんなことできないだろ。
出来るだろ。じゃないとboostのビルド不要なライブラリは実現できないよ。
「ビルド順はどうなるか」って、質問者はもちろん、
>>357 自身も理解してない気配。
分割コンパイルやリンクについてわかってないまま脱初心者とは。
ちなみに、グローバルやclass-staticな変数の初期化順については
何も規定されていないことが規定されている。
ということは、リンク順についてそれが当てはまることを意味するが
規格に「リンク」という単語が出ているかは知らない。
cppの分割については
>>358 と同じ。
classにわけたり、意味的なまとまりにわけたりして
まともなものを作るのなら分割するのが当然。
>>359 Javaチックな書き方ってことかね。
別にそれならそれで良いんじゃないの。
.hに全部書く、ということは、「ビルド(コンパイル)時間の短縮」なんて
露ほどにも考えていないということだから、
再利用もできるし分割コンパイルなんて必要無いかもね。
言い方がまずかったか。「できないものがある」。こうだな。 もしかして、全部 inline にしたり、あらかじめ obj にしたりしてあるのだろうか。
>>359 >クラスは基本的に .h で作って #include で取り込む、っていう方法を取っています。
>なので、再利用には困りません。
>ほとんどがヘッダっていう考え方がNG?
マジ??
その会社 大丈夫???
考えて見ればcppファイルが1つだけなら関数の定義とかを.hに書き込んでも
バイナリの時点で重複は起らないが(hでインクルードガードしていること前提ね。)
それにしても、、、ねぇ。。。
>>360 dllexport が必要な時と、main() 系、コールバック系以外はすべてヘッダファイルなんです。
クラスの定義や構造体など、ほとんど。
ヘッダファイルの考え方が違うのかな…
>>362 規定が無い点について理解しました。
確かにうちのプロジェクトのソースはビルド時間かなりかかるんです…
.cpp で書くと分割コンパイルされて速度が向上するということですね。
まったく知りませんでした。。
まさに java チックです。
なので、include 順序がかなり大事で問題も結構起きるんですよね。
でも私個人的には、c++ で開発しているので、c++ の基本を知りたいです。
>>363 全然、そんなことないんです><
おまけに、プリコンパイルヘッダもないので時間ばかりが掛かって…
>>365 ヘッダに定義を全部書いたら、クラスのインタフェースに全く影響を及ぼさない
変更であっても、そのヘッダに依存するソースファイルすべてが再コンパイル
されるじゃないか。その程度も分かってない会社って一体・・・
>>364 インクルードガードしてもできないよ。
インクルードガードは同一翻訳単位内でしか有効ではないから。
>>364 そうなんですよ!!
.cpp ファイルは main 用に1つだけあって、あとは .h の処理を呼び出したり、
クラスを生成してクラスに処理を任せたり、、、
グローバル関数までもが .h に居る始末です。
>>366 まさにその通りですね。
これでも一部上場なのですが、本当にお恥ずかしいです。
369 :
364 :2009/05/23(土) 23:25:54
>>367 いやできるでしょ。
cppが1つしかないんだぜ?
ってことは翻訳単位も(恐ろしいことだが)一つってことじゃん。
すでに拡張子の意味を逸脱した使い方なのはわかった
>>369 あぁ、そういうことか。理解したw
すごいな。
372 :
357 :2009/05/23(土) 23:33:35
結論としては、
>>370 がおっしゃっているように、
拡張子の意味を確実に逸脱しているのですね。
みなさんがおっしゃったように、リンクの意味を理解していなかったようです。
分割ビルドは十分理解できました。
今一度教えてください。みなさんは .h を基本的にどのような用途で利用されていますか?
また、現状のように .cpp を1つだけもち、ほとんどすべてを .h に置くことで発生しうる
考えられる問題がありましたら教えてください。
>>369 すみません、私は理解できませんでした。
まだ初心者であることを思い知りました。
翻訳単位が1つだと、恐ろしいものですか?時間が掛かる、という観点でしょうか。
373 :
369 :2009/05/23(土) 23:40:35
>>372 >翻訳単位が1つだと、恐ろしいものですか?
そんな開発者見たことないから、恐ろしいと形容した。
>今一度教えてください。みなさんは .h を基本的にどのような用途で利用されていますか?
あくまで宣言だけを書いておく。
MyClassを使う必要があればMyClass.hをインクルードする。
一方MyClass.cppにもMyClass.hをインクルードしておいて、別途コンパイルしておく。
こうすることで、MyClass.cppが変更されても他の大部分のcppは再コンパイルしないで済む。
あるいはMyClass.cppをコンパイルしてライブラリとして公開する場合、
他社には.hだけを見せるわけだから実装を隠せるとか。
>また、現状のように .cpp を1つだけもち、ほとんどすべてを .h に置くことで発生しうる
>考えられる問題がありましたら教えてください。
他の会社や組織に公開する時に実装がだだ漏れになるとか
つか、どんな教科書で勉強したんだよ。 大概の教科書は分割の仕方書いてあるだろ^^
>>372 ビルドに時間が掛かって仕方がないだろう
376 :
357 :2009/05/23(土) 23:54:38
>>323 なるほど、、、将来を見据えた設計をしながら開発してるんですね。
なんかもう、うちの会社が悩ましいです。
>>374 会社の研修では一切…
ちなみにほとんどのプロジェクトがそんな感じです。
java と COBOL 人間ばかりなので、include = そこにそのファイル内容を挿入、っていう
意味合いだけしか着目していないんだと思います。
>>375 その通りですね。勉強になりました。
今日皆さんにご指導いただいた内容を以って、会社の開発体制の改善を
促して以降と思います。
ありがとうございました。
まて、
>>357 は本当にC++を扱う一部上場企業に勤めているのか?
例えば、分割コンパイルには関係ないようなC++の問題だしても解けるか?
378 :
357 :2009/05/23(土) 23:55:32
どうせ元ABCのあそこだろ?
>>377 私も信じられなくなってきましたが、こんな開発者ばかりながらも、
一部上場です。
私はアセンブル系のドライバ開発あがりで、ウィザードを利用して ATL/WTL アプリケーションの
開発をやっているので、一から自分でファイルを作ってプロジェクトを構成したことがありませんでした。
20年弱もプログラミングをして来ましたが、初心者からはなかなか抜け出せませんね。
大変勉強になりました。
>>380 そうなのか。
じゃあもういっそC++やめて、各自が得意なCOBOLとかアセンブラやればいいのではないでしょうかね。。。
少なくとも一人、C++の知識がある人が居ないととんでもないことになるのでは。
まああなたがその一人になれば良いだけだが。
頑張ってください。
382 :
デフォルトの名無しさん :2009/05/24(日) 00:07:00
>>380 大丈夫。そのやり方で会社が回っているならそれで正しい。
開発の仕方に正解なんてないんだし、そもそも他と同じことをやっていたらこのご時世生き残れない。
君の会社は君の会社なりのやり方を見つけたんだと思う。だから生き残っているんだろう。
もっと、堂々としていいよ。
>>381 なかなか COBOL やアセンブルの案件が見つからなくなってきたんですよね。。
でも、頑張ります!ありがとうございます。
>>382 ありがとうございます。
基本をしっかり抑えた上で、スタイルを大事にして行くことにします。
>>380 優秀であってもドカタ企業のドカタじゃどうしよもないよ
一部上場の正社員とドカタ企業のドカタじゃ霄壌の差
言わなくてもわかってるからもうドカタに触れるのやめようよ 可哀想だろ俺が
一部上場ならお給金もそれなりでしょ まともな本買いましょうよ
初心者にまともな本買えって言っても、 どれがまともな本なのかわからんでしょ まともな本教えましょうよ
学生の勉強じゃない仕事の事なんだから、休みの日にでも本屋に出向いて 中を見て初心者なりでも”自分”で選ぶべきだと、俺は思う で、幾つかの本を読破してこそ、まともな本かどうかの判断が付く脱初心者になって行くんだと思う その最初のステップを”初心者”と言う理屈で飛ばすような奴が プログラムの本を読んで技術力を上げていくなんて出来ないだろ そもそも、本人が教えてと言ってるならともかく 初心者なんだから教えるべき、と言って自分は教えてない奴は好きじゃないw
兎にも角にも禿本は重要だよな。 特に後半の設計に関する部分を読んでない人は多いと思うけど、色々含蓄あるし。
俺が書いたネタレスに入魂レスとは....
ネタと分かるように語尾を
>>386 と同じにしたのに
釣られる奴居るんだな
>>388 長々と小言を言う暇があるなら、自分が薦める本を挙げればいいのに。
>>390 釣りならVIPでも行ってやれば?
だから最初の理解なんて人それぞれ 俺が良いと言ったって、合う合わないがある、だから教えないし、 自分でググるなり、本を手に取れって言ってるじゃん アンタゆとり?
釣りに延々とマジレスしてきもいな
以下のプログラムがうまく行かないのですが、 解決方法を教えて下さい。 5 class B; 6 7 class A{ 8 public: 9 int hoge; 10 A(int i){ i = hoge; } 11 12 B conv(){ return B(hoge); } 13 }; 14 15 class B{ 16 public: 17 int hoge; 18 B(int i){ i = hoge; } 19 20 A conv(){ return A(hoge); } 21 }; ------------------- エラー test.cpp: In member function ‘B A::conv()’: test.cpp:12: error: return type ‘struct B’ is incomplete test.cpp:12: error: invalid use of incomplete type ‘struct B’ test.cpp:5: error: forward declaration of ‘struct B’
Bの定義より後にA::convの定義を置けば上手くいく。 class B; class A { public: int hoge; A(int i) { i = hoge; } B conv(); }; class B { public: int hoge; B(int i) { i = hoge; } A conv() { return A(hoge); } }; B A::conv(){ return B(hoge); }
class B; class A { ... B conv(); ... }; class B { ... }; B A::conv() { return B(...); }
complexは実数、虚数にreal()、imag()でアクセスするわけですが、 この関数って参照返すだけだから、 それだったら内部の実数、虚数変数に直接アクセスした方が関数呼び出し無い分早いだろうし、 ソースコードも見やすく(多分)なると思うのですが、 これには何か理由があるのでしょうか?
>>398 基本的に内部の実装に触れられるようにしちゃうと
いざインターフェースは変わらないが実装が変わるような仕様変更をするときに
悲劇がおこるからとか。
あと、関数呼出のオーバーヘッドなんてないと思っていいよ。 それくらいコンパイラの最適化でいともたやすく消え去るられる。
そんなことはない だったらなぜわざわざinlineなんて予約語が用意されてるんだ? 関数呼び出しを減らすのは高速化の基本のキだ ウソを教えるのはやめろ
現在は なんでもかんでもゲッタセッタ教 の勢が強いから 狂信者の戯言は聞き流して己が道を進めばいいと思うよ
下駄雪駄教徒だって、下駄雪駄は基本的にインライン関数にするだろう アウトラインの下駄雪駄なんておぞましいものは狂信者でも書くわけがない 少なくとも長いループ内では、アウトライン関数を呼んではいけない これは今も重要なガイドラインだ
少なくともC++でフィールド変数直接アクセスするのは
百害あって一利なしだな。
>>402 >>401 が言ってるのはreal/imagの話だろ。
言葉足らずならそう指摘すればいいのに。力抜けよ。
せったげったって言うけどさ hoge.hage.foo.bar.set_value(0); とかはあったとしても hoge.get_hage().get_foo().get_bar().set_value(0); なんてことはしないよね この辺みんなどうしてるんだろ。 hage や foo は public なメンバにするよね?でもそれだと統一感ないよね?
どっちもねーよ
データ主体なものは構造体にしている メンバ関数はコンストラクタ、コピー、シライライズ、ダンプ、アサートぐらいしか定義しない それと同じ目的の変数は構造体にまとめる class A
途中で送ってしまったぜ 後ろの段落は class の中で struct xxx_param とか struct xxx_item, xxx_state とかを定義して まとめてあつかう
おなじくどっちもねーよ > hoge.hage.foo この辺までですでに内部状態の一貫性を壊していると思われ(setの場合)。 設計が悪いから作り直せ。
え?でもさ、よくしらないけど、フォームアプリなんて System.Form.SetValue() みたいにどんどん深くなっていってない? 実モデルでたとえても、例えば 部屋A.本棚B.本C.ページD.GetText(); みたいな例は十分にありえるんじゃないの?
>>402 は今でもregisterを使っているのだろうか。
せめてこうだろ void foo::set_bar_value(int n) { bar.set_value(n); } void hage::set_bar_value(int n) { foo.set_bar_value(n); } void hoge::set_bar_value(int n) { hage.set_bar_value(n); } hoge.set_bar_value(0); 俺はvector3やmatrix44みたいなのは公開してるなあ。 あとは、クラスとして独立させるほどでもないが、関連のあるメンバ変数をグループ化したいときに structを使ってる。
>>413 System.Form.SetValue()
どこのC#?
あとそれ名前空間と混ざってるから。
でも名前空間って要するに全メンバがpublic静的なクラスのことだろ
しょぼい設計でなければ 名前空間で内部状態を壊されることはないから問題ない。
class A{ B* get(); } というクラスで、get()メソッドをインライン関数にしたい テンプレートクラスと同様に同じヘッダファイルに実装を書く場合、 inline B* A::get(){ コード } の「inline」は意味があるのでしょうか?
ない というか意味があるかないかで言うなら、inlineは常に意味がない コンパイラは自由にインライン化要請を無視できるし、要請されてない関数をインライン化することが出来る
規格上はそうだが、一応現実的には意味はあるから、意味なしと言い切ってしまうのは誤解を招くのでは。 例えば俺が使っているコンパイラは「inline指定に従う/無視する」「inline指定がなくても勝手にinline化する/しない」 などの指示を自分で出すことができる。
423 :
422 :2009/05/24(日) 17:26:22
もちろん環境依存の話だから、詳しくは「自分が使ってるコンパイラについて調べてね」ってことだけど。
inlineは、コンパイラの最適化云々ではなく、 ヘッダに直接(= インラインで)定義するぞ、という意味だと思えばいい。
>>424 変な誤解を生むから詳しく知らないなら
黙ってるか断定的に書くな。
>>424 適当なこと書くなよ。
cppファイルにてもinlineは書けるわけだし
もう何が何なのかw
>>424 インラインに”ヘッダに直接”という意味があったなんて白なkったおれはどうすればいい?
"C++" "ヘッダに直接" "インライン"の検索結果 5 件中 1 - 5 件目 (0.33 秒)
429 :
426 :2009/05/24(日) 18:08:40
ところで
>>420 でinlineを付けなかったらリンカエラーにならない?
そういう意味でinlineはいると思うんだけど。
431 :
デフォルトの名無しさん :2009/05/24(日) 18:37:06
んなわけない。
>>430 よくわからないけどオブジェクトコードにクロージャっぽいのがつくられるきがするぅ
int DLLAPI (*mcOpenDevice ) (void) = NULL; あるDLLについてたヘッダ内の記載なんですがVCで「構文エラー : '('」が出ます カッコの数は合ってるし、関数ポインタの宣言としてもおかしくないように見えるのですが 詳しい方から見て何か違和感はありますでしょうか? ちなみに #define DLLAPI WINAPI されてます
ん、俺の環境(gcc 3.4.5)だと、ヘッダファイルのクラス定義内部じゃないところにinlineがついてない関数定義があって それを複数の翻訳単位でインクルードしてコンパイルしてリンクすると、多重定義エラーでるなぁ。
問題ないと思う 多分その直前に何かおかしい所がありそう
WINAPIを関数名と勘違いしちゃったんだろうな。
>>435 ありがとうございます
自分の作ったのでも結構悩むのに、さらに人の作ったのだと難度高いです・・・
もうちょっと見直してきます
プリプロセスだけ通してみるとか
先に<windows.h>をインクルードしたらいいと思う。
>>438 プリプロセッサ以外の記述を削除ってことですか?
>>439 <windows.h>とかメジャー系はいくつか試したんですがダメでした・・・
441 :
433 :2009/05/24(日) 19:35:13
とりあえず #define WINAPI か #define WINAPI __stdcall って書いとけ。
443 :
433 :2009/05/24(日) 19:52:22
>>438 すんません、勘違いしてました
/E /Pで.i吐かせて該当行見ましたら
int __stdcall (*mcOpenDevice ) (void) = ((void *)0);
と展開されてました、他の箇所も見た感じ悪くはなさげなのです
445 :
420 :2009/05/24(日) 20:19:30
>>421-434 VC++2003を使っていて、今のところ1つのcppファイルからしかインクルードしてないので
inlineを付けても付けなくても問題はなかったのですが、
付けないとcppファイル毎に関数が定義されているとみなされる=
>>430 や
>>434 ということなんでしょうね。
どうもありがとうございました。
446 :
433 :2009/05/24(日) 20:19:42
>>444 ありがとうございます、無事ビルド通りました
>>436 さんも多分同じこと指摘してくれてたんですよね、分からなくて申し訳ないです
みなさんのおかげで先に進めそうです
本当にありがとうございました。
超初心者ですがコンパイラ何使ったらいでしょう?
gcc
書き忘れました windowsで使えるものをお願いします
>>448 よくわからないのでとりあえずぐぐってみます
ありがとうございます
>450 WinならMinGW まあgccなんだけどな
452 :
デフォルトの名無しさん :2009/05/24(日) 21:13:37
454 :
デフォルトの名無しさん :2009/05/24(日) 21:35:25
Toubo C++
>>454 初めて聞いた。
そしてググってみてちょっと面白かった。
7件しかヒットしないぞ? しかも全部中国。
昔はTurboCといえば、M$としのぎを削った人気コンパイラだったのだよ。
いやTouboだし。
Toubo C++ 検索したら漢字ばっかで いじる勇気がでない。
JIS X3014 6.6.3 return の 2 の最終行、「未定」が「末定」になってるw
しばらくVBAばっかりいじってたから、C++のウィンドウの扱いが面倒に思えて困る いつもVCの空のプロジェクトにダイアログリソース突っ込んで出してるんだが ひょっとして空のプロジェクト使わなければC#とかみたいに簡単に扱えるのかな? 空じゃないプロジェクトって最初からコードいっぱい書いてて抵抗あったから今まで触ったこと無いんだ
スレ違いすぎるだろ…
>>461 vcでポトペタできるのはダイアログだけだよ
ウィンドウはムリポ
スケルトンコードは慣れかな
どうせ似たようなコード書くんだし
続きはVSスレかWinAPIスレかMFCスレで
461です、スレ違いすまんかった 覗いてみた感じここの奴は視野が広そうだったから、ここで聞いてしまった 数年前に比べて大して便利になってないという事だな 昔作ったスケルトン掃除して使ってみるよ、ありがとう
465 :
デフォルトの名無しさん :2009/05/25(月) 19:30:32
blitz::Arrayって何を意味してる? ググってもわからんかった
>>465 C++の言語に関する話としては
blitzというクラスの、Arrayというメンバ。もしくは、blitzという名前空間に含まれる Array というもの。
実際ぐぐってみたところ、Blitz++というライブラリがあるみたいだね。
このライブラリでblitzという名前空間を使っているようだ。
467 :
466 :2009/05/25(月) 19:47:15
468 :
デフォルトの名無しさん :2009/05/25(月) 20:11:46
>>467 回答どうも 軽く読んでみた。
じゃあどうやら 『blitz::Array< int, 2 > A 』 って宣言だと
『中に整数値の入る2次元の行列式の定義をbiltzっていう名前空間でやってる』って感じでいいのかね
Arrayは直訳で行列じゃなくて配列なのが気になるんだけどね・・・
>>468 細かいとこちょっと違うけど概ねそんな感じ。
470 :
デフォルトの名無しさん :2009/05/25(月) 20:21:33
>>469 ごめん Cは前々からやってたんだけどC++は最近独学で始めたばっかりなんだわ…
で、違うところって? (俺の知識が浅いから、伝わらなそうだったらスルーしてくれ)
>>470 ごめん、ちょっと忙しくなるから、後でまた来るわ
そのときまでに他のレスがついてなかったら書くよ
472 :
471 :2009/05/25(月) 21:07:14
まず、blitz::Array そのものは blitz名前空間の中に入ってるが、 blitz::Array< int, 2 > A; とした場合、(これ自体をblitz名前空間の中に書かない限り)このAはblitz名前空間には入らない。 あと、「行列式」じゃなくて「行列」だな。(似てるけど意味が違う)
行列式でいいだろ 行列を表すexpressionなんだから determinantのことを言いたいなら、それは揚げ足取りと言うものだ 感心しない
C++始めたばかりなら名前空間をよく分かってないかもしれんが まあ、ちょっと語弊があるけど “blitz::Array<int,2>” で1つのクラス名だと思ってしまってもよい。 int a; がint型の変数aであるのと同じように blitz::Array<int,2> a; は blitz::Array<int,2> 型の変数aだ。 名前空間ってのは、例えばライブラリ作成者がArrayっていう名前のものを提供している場合、 利用者のコードにもArrayってのがあると名前が衝突してしまって不都合だから、 名前がぶつからないように blitz:: という修飾をつけてるんだと思えばよい。
>>473 そうか? 俺はどうしても気になるし明確に誤りだと思うが、まあ揚げ足取りと取られるならこれ以上は言うまい。
行列式は駄目でしょ
478 :
470 :2009/05/25(月) 22:04:48
なんか複数人からレスもらってるみたいで、皆さんどうもありがとう blitz::Array<int,2> 型の変数aって感じは掴めてたんだけど、そもそもblitz::Arrayは何を表現するのかが不明で困ってたのよ それはそうとプログラム板って初めて来たけどID表示ないんだな、不便じゃない?
>>476 そういう言い方はたとえ2chでもどうかと思うぞ
まぁでも
行列と行列式は…何と何くらい違うんだろ。ブドウとグレープフルーツくらい?
>>478 スクリプト書けばID丸わかりだから不便じゃないよ。
481 :
デフォルトの名無しさん :2009/05/25(月) 22:53:31
IDが分からなくても別に不便を感じたことない。
Win32APIスレはなりすましで大変なことに…
別に大変じゃないし
>>395 A(int i) { i = hoge; } ↑ は何をしたいの?
とてもサイズの大きなメンバ変数があったとき、 「そのメンバ変数のポインタを返すようなメンバ関数を作る」か、 「そのメンバ変数のコピーを返すようなメンバ関数を作る」か、 どちらがオブジェクト指向としてはよろしいのでしょうか? 前者だと、privateなメンバ変数に対して外部からタッチしてしまうことになりますが、 無駄が少ないように思えます。 後者だとprivateなメンバ変数を保護(?)できるというか、そういう考え方に則しているような気がしますが、 無駄にメモリを食ってしまう気がします。 完全に独学のため、ちょっと意味不明な単語が混じっているかもしれませんが、 教えてください。よろしくお願いします。
int gethoge();のような関数を作るのはよろしくないということなんでしょうか? ↑だとintのコピーを返す関数に当たると思うのですが、問題外となると、ちょっと目の前が真っ暗になってきました…。
privateな構造がしゃしゃり出てくるクラス設計が間違い 最初からpublicに分類すべき それで問題が出るなら普通の人なら根本から作り直すね
すみません、現段階ではちょっと理解できないのですが、文献を漁ってなんとかしてみます。 貴重なアドバイスありがとうございます。
>>485 const なポインタ or 参照を返せば、他から変更はできないけど、 他の部分がそのオブジェクトの構造に依存することになるね
アクセス制御がなんのためにあるのかという根本が分かってないように見える
>>485 まあ要するに、
クラスのクライアント(使う人)が
privateなメンバ変数(およびprivateメンバ関数)
については何も知らなくても
publicなメンバ関数を見るだけで
使えるように設計すべき
ということだよ。
これはすなわち、public/protectedなメンバ関数以外が変わっても
クライアントが書いたコードには影響がないということ。
ちなみにpublicなメンバ変数なんて大抵はクソ設計の証。
485じゃないけど
>>492 それは基本的にはカプセル化に重点を置いてコードを書いた方が良い、ということで良いんでしょうか?
494 :
492 :2009/05/26(火) 20:41:33
>>493 そう。基本的にはね。
オブジェクト指向プログラミング (OOP; object-oriented programming)
においてカプセル化はとーーっても大事。
たまにいっそ全部publicにということで構造体structを使うことがあるけど
基本的にはそういうこと。
なんとなく分かってきました、ありがとうございます
まあ現実的にはpublic変数だの参照返しも使うことはあるけどね
ねえよ
無意味な隠ぺい無意味な複スレッドは考える力が足りない人が一度はハマる道程だからね
499 :
492 :2009/05/26(火) 21:54:08
現実にはそういう場合もあるかもしれないけど、 「良いクラス設計」の話に限った場合、フツーはない。 「全部publicにということで構造体struct」 は返り値に複数の情報を持たせたい時とかにありえる。 ただ複数の型を束ねただけ。
GetとSetがズラリと並んだクラスは結構見るな
ねえよ
>>500 学生の頃作ったプログラム見直してみるとGetとSet多用しててえらいことになってた
今でもうまい設計はできないけど、他で使うならpublicでいいよねって話だよな
Effective C++には最悪でもget()とset()用意しろって書いてあるよ^^
structでメンバ変数をpublicにするのは
>>499 の言うとおり、値を束ねただけのものとして、
構造体を値として扱う場合にだけ許される。
Effective C++やC++ Coding Standards、Google Coding Standardsなんかを
ひとつも読んでいない人間はC++触らないでください
>>503 センセー俺1つも読んだことないんですけどー
読むだけなら馬鹿でもできるから気にする必要無い
class A{ int a; public: int get(){return a;} void set(int i){a = i;} }; こういうのはさすがにpublic派のほうが多い気がする
宗教になぞらえられたりする理由なんだろうけど本人が気付くまで周りが何を言っても無駄なんだよね 距離を置いて厄災に巻き込まれないようにするだけ
>>506 が「何を」 public にするのかは知らないけど、
もし int a を public にする気なら、豆腐の角に頭をぶつけて死ねといいたい
メンバ変数をpublicに置くような人間は抽象化には興味ないんだろうな。 C++使う理由がないよ。多分。
aがクラスや配列やポインタなら全くもってその通りだがintだぜ? こんなプリミティブなメンバまで変更しなきゃならない時にはどうせインターフェースも変更入るよ そこまでいちいちgetset噛ませと言い出すとちょっと原理主義すぎて現実的でない
こういうとき、プロパティのある言語がうらやましいと思う。
もしgetterやsetterで参照する対象が巨大な配列やクラスだったら 重いコピーが発生する事を覚悟しなければならない つまり巨大な配列やクラスはgetterやsetterの対象にはならない
>>510 返すのがintだからどうだって話じゃないだろ。たとえば
class A{
int a,b,c,d,e,f,g,h,i,j,k,l,m,n;
以下略
};
こんなのの実装をimplイディオムに変えたいと思ったときどうすんだよって話。
どこの世界も原理主義には付き合ってられない
getとsetをpublicで公開するということは、 「いつでも誰でも見ていいし好き勝手に変えてもいい『何か』を持ってますよ」ということを 外部に向けて大っぴらに公開しているということです したがって、そのセマンティクスを変更するのはインターフェースの変更なんだから getとsetを使っている全ての箇所に影響が出てしまいます これってよく見ると『何か』を変数としてpublicで公開した時と状況はまったく変わりませんね publicなgetとsetを両方用意するというのは、同じ事を回りくどく書かせるだけであって 可読性も保守性も一切上がりません intだろうと何だろうと何でもかんでもgetsetというのは罠であり、有害な迷信です public変数のセマンティクスを持つものはpublic変数でいいんです
わずかなタイプ数の増加が"現実的"でない理由って何よ?
privateに固執するおまえはマダマダ無能と言われてるんだよ。
無意味なget setで行が肥大化するのはプログラムを見づらくするだけ。 原理主義的には、カプセル化した気分に浸れていい
現実には、そのセッタでだた代入するだけなんてことはなくて、 たいてい、ついでにどこかに値の変更を通知したり、 入力値が範囲外なら例外投げるようにしたりしていて、 単純にメンバ変数をpublicにできる場合なんて全然ないと思うんだけど。 そんな場合の話はしていないって?
今話題に上がっているのは、ただのset get。 意味があるのは問題なし。
マルチスレッドから操作されるようになったので、 aを防御したくなったらどうするの? aが頻繁に変更されるようになったので、 毎回最新の値をサーバから取得したくなったらどうするの? aに連動してbも変更したくなったらどうするの? 正当な値だけ受け付けるようにしたくなったらどうするの? aが更新されたことをBに通知してあげたくなったらどうするの? 将来行われる変更を全部見通すことができるの?
>>519 そういう色んなことをする関数は単純なsetではなく、もっと意味のある名前を付けられるはず
なんかの大きさならresizeとか、通知するんだったらnoticeとか
その相方はgetとしか言い様がないこともあるだろうけどさ
両方とも本当にget,setとしか名付けようもないようなものは、その意味合いは内部的にも外部的にも
ただのpublicメンバ変数だと思うんだけどなぁ
>>522 排他制御はともかく、他はgetXXだのsetXXだのという名前を付けるべき操作ではない
>>523 何を根拠に。
ちょっとした処理付きのgetXX/setXXなんて普通に使うぞ?
お行儀の悪いプログラムってやつだな
もういいからsetしようとしたら強制的に例外投げろよ
>>527 それもpublicメンバ変数じゃできないな。
アクセス違反がせいぜい。
>>524 例えば「正当な値だけ受け付ける」ようにsetXXを変更したとしようか
そうなると不当な値が入ってきたらエラーなり例外なりを返すんだろうが、
旧バージョンのsetXXを使ったコードは当然そのエラーに対応する処理をしていないので問題が起こる
つまり、この変更はインターフェースの変更であって、全てのsetXXを使用するコードに修正を迫るものであるわけだ
素直にsetXXの呼び出しを全部修正してもいいし、旧setXXとは機能が違う新setXXを(機能に見合った名前で)
新しく別に作って適宜置き換えるのでもいいが、結局はsetXXの呼び出しは全てチェックする必要がある
でも、どうせset箇所を全部見直す必要がある変更なんだから
最初からpublic変数で書いて、必要になってからset関数を書いてもまったく同じだろ?
>>529 確かに、エラーの追加はインターフェースの変更だ。
そこは全面同意。
でも1つしか答えてないぞ。
> getとsetをpublicで公開するということは、 > 「いつでも誰でも見ていいし好き勝手に変えてもいい『何か』を持ってますよ」ということを > 外部に向けて大っぴらに公開しているということです この認識は間違い。 getとsetをpublicで公開するということは誰でも自由に行ってもいいのはただセッタゲッタの呼び出しだけで その結果は呼び出し側の都合ではなくクラスの都合で決定されます。 クラスの都合を無視してクラスの状態の参照や変更を行うことはできませんということをいっている。 > 例えば「正当な値だけ受け付ける」ようにsetXXを変更したとしようか > そうなると不当な値が入ってきたらエラーなり例外なりを返すんだろうが、 > 旧バージョンのsetXXを使ったコードは当然そのエラーに対応する処理をしていないので問題が起こる こうした場合は実装の変更ではなく仕様の変更なのでセッタゲッタによるカプセル化(=実装の隠蔽)のメリットとは無関係。
個人的には自由変数を1個インターフェースとして公開するごとに
そのクラスの内部設計の自由度が減るのがいやだな
あとは
>>519 と同じ意見でただ代入するってのはあまりない
たいていマルチスレッド用の排他処理がくっついたりする
メソッドとメンバしかないC++が全て悪い。 object.set_value2( object.get_value0()->get_value1() ); こう書くより、 object.value2 = object.value0->value1; こう書いた方が、見やすいものなぁ。
>>533 operator =で見やすいほうの書き方にできるのでは?
C++知らない俺が言うのもなんだけど、set/getなんていう 低レベルのインタフェース作るのが間違ってるんだよ。 もっと抽象化された機能のメソッドを作るべき
>>535 >10年前に作られた言語
wikipediaによると標準化からは10年だが、C++2.0から20年、前身のC with Classesから30年のようだ
D&Eなんかで示された考え方も今では古くなりつつあるのかと思うと少し寂しくなる
何でさっき知ったばかりなのに寂しがってんだよw
>>536 get/set全てが低レベルなインターフェースとも限らないけどね
2,3行目は俺も同じ意見だ
結局、変数をpublicに置くような連中に何を言っても無駄ということが証明された様子。
>>515 に対する反論はEffective C++にずばり書かれてる。
ちなみに、Effective C++の著者であるメイヤーは別の書物、
Effective STLの中でそういう連中とは距離を取れと書いている。
まさに
>>507 の予言どおりだ。
ところで、メンバ変数をpublicにおく場合ももちろんある。
議論の冒頭、
>>499 はちゃんとそういう例外事項があることを認めている。
C++ Coding Standardsの第41項でも例外事項を設けているし、
setとgetの功罪(設計の過ち)についても言及している。
だから、「原理主義」でくくるのは議論の前提を無視している。
C++ Coding StandardsはC++関係の本の中でも厚さが特に薄い本だが 内容は濃いな
wikipediaのメソッドの記事にアクセサ論争って項目があるんだな やっぱ昔から争ってる内容なのか
boost::arrayはpublicにメンバ変数を置いてるけどなぁ・・・。 これもだめなのか?
安全性を重視するか、高速性を重視するかは、設計者に委ねられてる どっちが正解とかいうものではない
ときどき「高速化するため」といって安全性をスポイルすることを正当化する人間が出てくるが そういう人間もCoding Standardsを読むべきだな。 高速化が正当化されるには「時期」があることが説明されている。 アジャイルプラクティスとかもあわせて読んでおきたい。
性的な意味で
>>545 だから詳しく知らないなら断言するなよ。
getter/setterの速度がどうとか言ってる奴は
議論に参加する資格すらないから。
なんじゃこりゃ。
>>485 の質問からなんでこんな流れになるのかさっぱりわからん。
ここは聞かれてもいない知識をひけらかす似非回答者たちのオナニー相談室ですか?
はいそうです
>>550 申し訳ありません。
ここは質問に淡々と答えるだけの
ボランティアたちによる慈善スレでした。
以後気をつけます。
でいいですか?
結局
>>485 に対する解答が1つも見当たらないんだが…
そもそも質問には、public なんて単語すら全く出てきてないよ?
>とてもサイズの大きなメンバ変数があったとき、
>「そのメンバ変数のポインタを返すようなメンバ関数を作る」か、
>「そのメンバ変数のコピーを返すようなメンバ関数を作る」か、
>どちらがオブジェクト指向としてはよろしいのでしょうか?
結局どうすればいいのよこれ?俺も知りたいよ
たぶん、オブジェクト指向の観点からは「どうでもいい」。 実際には実行速度とかconstnessとかあるだろうが、オブジェクト指向の問題ではないかと。
え、まじでいいの? 質問者の書き方だと、その巨大なメンバ変数は外部からは readonly にしたいんだと思うけど、 ポインタを返すと write できちゃうってのはオブジェクト指向からすると問題なんじゃないの? 俺の理解不足なのか…すまない
問題な事もあれば問題でない事もある。全てのパターンに付いて書いていたらきりがない。 その場その場で最も適当(若しくは、それなりに妥当)な方法を選ぶのがC++。
なるほどね オブジェクト指向的には値を返すべきだが、 実行速度が必要な場合などは、オブジェクト指向に捕らわれるよりも処理速度を優先させてもいい 的な答えだと思ってた。そうでもないのか。さんきゅー。
以後、大きなサイズのメンバ変数を持っているクラスをA、メンバ変数をaとする。 1. 本当にaを外部に晒す必要があるのかよく考える。 2. Aに処理を任せられないかよく考える。 3. Aの名前を変えてみて、やっぱりAに任せられないかよく考える。 4. aの要素をすべて晒す必要があるのかよく考える。 それでもだめなら、 返却するメンバ変数も安全に作られているなら、 constのポインタか参照を返すようにすればそれで十分。 呼ばれるたびに新たなオブジェクトの生成が必要なら躊躇せずコピーする。 悪意あるプログラムから保護する必要がある場合も躊躇せずコピーするが、 たいていはそれだけでは不十分だと思われ。 90点回答だ。おまいらひれ伏せ。 異論はオカマ言葉で行うこと。
>>558 あたしの身体はひれ伏してるのに、あたしの息子が……どうしてくれんのよ! もう!
参照するだけで値はいじらせない参照ができればいいんですよね イテレータ的なものを使うという案は出ていないようですが この方法はそれほどスマートな解決策ではないということでしょうか
えっと、参照するだけで値をいじらせないなら、const参照を使えばいいわけだが。
>>485 って、例えば
class Person{
std::string name_;
public:
std::string *name() const { return &name_;} //A
std::string name() const { return name_;} //B
const std::string &name() const { return name_;} //C
const std::string *name() const { return &name_;} //D
};
みたいなのでAにするかBにするかってことだよね。
「とてもサイズの大きな」ってのが曖昧だけど、つまりコピーにコストがかか
るものってことだろう。
つまり回答は
>>490 だな(C,D)。
もちろんクラスやメンバの意味が変われば
>>486 もあるだろうけど、頭ごなしに
「問題外」というのは何か勘違いや思い込みがあるのだろう。
564 :
563 :2009/05/28(木) 09:43:56
ああ、constを打つクセが…… - std::string *name() const { return &name_;} //A + std::string *name() { return &name_;} //A
>>563 そうかな
俺も
「データメンバAがあったとき、それを扱うメンバ関数Bはどう作ればオブジェクト指向っぽいでしょうか」
という質問はおかしいと思う
nameの例はあくまでnameがあってこそのname_でしょ?
nameっていっぱい書くとなめなめみたいでいやだよね
なるほどね 「とてもサイズの大きな」ってのが、そもそもおかしいよな。 大きかろうが小さかろうが、オブジェクト指向な振る舞いは同じはず。
実用上の振る舞いに問題が出るだろう。
タイ米はたいて買ったのに 古米に違いが出たら 悲しいやね
うん
ふ、古米・・・
572 :
デフォルトの名無しさん :2009/05/28(木) 21:12:43
cygwinのgccは3.45だっけ? 後何カ所止まるか想像もできないのに 全部この板で聞いて解決するつもり? 無駄な努力はやめてgccバージョンあげとけ。 あと質問の仕方の問題点について20字以内で述べなさい。
環境依存で標準C++に何の関係もない。スレ違い
Effective C++を買おうと思うんだが、原著三版ってやつで大丈夫?
>>575 俺はそれ買ってみた。
とても良かった。
vsいれたほうがいいんちゃうんかと
じゃあ原著vs三版買うよ 改訂2版とか言うのがあるから、どっちにしたらいいのか迷ったんだけど 発売日で比べりゃ一目瞭然だったわ サンクス
俺は両方買った というか最初改訂2版しかなくて買ったら次本屋に行ったら 第3版があって俺涙目orz
580 :
デフォルトの名無しさん :2009/05/29(金) 21:23:58
Visual C++ 入れたいんだけど、Express Editionてやつだと インスコ先にDドラ指定してもCドラを800MBぐらい食うのよ(今Cドラは1.5GBぐらいしか空きない) スリム版みたいなのってないんですかね
ないよ
582 :
デフォルトの名無しさん :2009/05/29(金) 22:00:41
ぽいね
Cドライブを空けろ
新しくプロジェクトを作った後ソースやヘッダファイルを丸々コピーしてフォルダに移した後、既成項目の追加をして同じものを作ったつもりなのですが アプリケーション更生が正しくないためアプリケーションの開始に失敗しました マニフェストファイルを参照してエラーの原因を調べてください と出ます、何がおかしいのでしょうか?DXUTを使っています
585 :
デフォルトの名無しさん :2009/05/29(金) 22:14:46
了解、といっても残り1GBからCCleanerかけてやっと1.5GBなんだよね・・ 正直もう消すものないんだけどね 使ってない付属ソフトでも消そうかな・・・ 答えてくれた人ありがとう!
>>585 Dドライブには空きがあるのなら、
ジャンクションやシンボリックリンク使ってDドライブにファイルを移せばいい。
587 :
デフォルトの名無しさん :2009/05/29(金) 23:20:46
>>586 ジャンクションやシンボリックリンクって
もしかしてXPだと無理? ググったらなんかVistaで使用可能とかでてきたんだけど
マウントのことなら別にWindows 2000でも出来てたが。
590 :
デフォルトの名無しさん :2009/05/29(金) 23:59:50
00?
>>587 たしかできるはずー
EeePC901で容量稼ぐためにがんばったことがあった
592 :
デフォルトの名無しさん :2009/05/30(土) 00:57:10
今、フリーのBCCでWindowsのコンソールのプログラム書いてたんだが、 アラインメント関係がわからない。 とりあえず、現状を書くとある大きい処理がmain関数中に埋まってたんだが、 やたら遅いから(まぁ、処理量もあるんだが)なんとなく関数化してソースの先頭に 移動させたら早くなって、アラインメントが原因だと思うんだ。 で、ものとしては for(i = 0; i<32*32*32; i++)for(i2 = 0; i2<32*32*32; i2++); だけなんだが、原因は何だろう? (関数の位置なのか、変数の位置なのか。 アラインメントがどのように影響するか分からないので、 どの辺に注意したらいいかおしえてほしい) へたくそな文章でごめんなさい。。。分かる人お願いします。
本当にアラインメントなのか? map出力して確かめてみたらどうよ(bcc32なら-M)
>関数化してソースの先頭に >移動させたら レジスタ割付されただけじゃねーの
このスレに書くべき話題かどうか分からないのだが、static_castってかなり誤解を受けてない? 俺もいくつかの入門向けサイトを見て「暗黙の変換を明示的に書くというだけの意味しかないのかな?」 と勘違いしていたが、実際には暗黙の変換が認められないいくつかのケースでもstatic_castができる。 このことってどれくらい知られてるんだろ。
そうかな?俺はdynamic⇔staticで対称になってて static_castはコンパイル時にキャストに問題がないか判断するもの、って覚えてたが むしろ「暗黙の変換を明示的に書く」って解説してるサイトがあるのか? それは問題がある解説に見えるなぁ
自分は、static_castで可能なのは暗黙の変換とその逆向き、そしてユーザ定義変換と覚えていた。
598 :
595 :2009/05/30(土) 03:25:48
うーん、改めて見てみると、俺が初心者時代に変な思い込みしただけかもしれん。まあいいや。
599 :
デフォルトの名無しさん :2009/05/30(土) 08:16:34
(なんかVC++から派生してC++の話と離れてきてる感じですいません・・・)
ttp://www.forest.impress.co.jp/article/2008/12/11/linkshellext.html ここによると、
>また、本ソフトは“ジャンクション”や“ハードリンク”なども作成可能。
>Windows Vistaでは多くの場合、シンボリックリンク以外を利用する必要はないが、
>Windows XP以下のバージョンのWindowsではシンボリックリンクが利用できないので、
>これらで代用しよう。
ってあるからシンボリックリンクはだめだけどジャンクションはいいみたいです
で、つまりCドラのファイルをDドラに移して、CドラにはDドラの移転先へのリンクだけ残しておけばいい
みたいな感じでいいんでしょうかね?
std::vector<double> a; std::vector<double> b = a; この場合って、 コピーコンストラクタが呼ばれるのか、代入演算子が呼ばれるのか コンパイラによって違うんだっけ? どこかに書いてあった気がするんだが忘れてしまった。
const_cast…cv修飾子を除去するのに使う。 reinterpret_cast…ポインタと整数型の変換に使う。 dynamic_cast…略。滅多に使わず事足りる。 static_cast…以上3つ以外 っていう認識でいるわ。
>>600 カンチガイしているな
std::vector<double> a;//デフォルトコンストラクタ
std::vector<double> b = a;//コピーコンストラクタ
これらは「新しいオブジェクトを作る(construct)」なのだから
呼ばれるのは両方ともconstructor。
そして呼ばれるのは当然
前者はデフォルトコンストラクタ、後者はコピーコンストラクタ。
一方、
std::vector<double> x;//デフォルトコンストラクタ
このとき
x=b;
としたら、これは新しいオブジェクトを作るわけではないのだから
代入演算子operator =
が呼ばれる。
>>602 君はキャストしない方がいい。いつか死ぬ。
dynamic_castを多用するようになってきたら設計ミスを疑った方がいい。
俺はクロスキャストの時だけdynamic_castを使っているけどな
やむを得ない場合もあるけど、クロスキャストを多用するのも以下略
クロスキャストは仮想関数では解決できないだろ
そういう状況が多数生まれる時点で糞設計ってことを言いたかったんだけど。
誰も「多数」とは言ってないわけだが
>>614 >そういう状況が多数生まれる
の多数ってのは
>クロスキャストを多用する
の意味なんじゃないの?
なんで分からないの?w
全くの初心者でお聞きしたいんですが、C++の講義ではTurboCというソフトを使って講義が進められるのですが 自宅のPCで同じことをするにはどういったソフトを使えば良いのでしょうか? 講義も全くわからずコンパイルという意味も全くわからずソフトを探すこともままなりません。どうかご教授ください。
誰もクロスキャストを「多用する」とは言ってないわけだが
何一人でエキサイトしてんの?
>>619 お前は誰に対するレス?
安価つけてくれ、分からないから。
>>621 いや、それを明らかにしておかないと、
俺が論破してもはぐらかされるだろ。
そういうヤツが多すぎるから、はっきりさせないと不毛な書き込みになる。
初めから不毛だと気づいてないのかこの馬鹿は
2chで議論すること自体不毛だよな。
まあせめてID付きの板でやるとか、コテハン付けるとかね。
鏡?ディスプレイで十分なのに鏡?なぜに?
dynamic_castよりconst_castやreinterpret_castの方が多用したらまずいと思うんだけどどうだろうか const_castなんかいまだに使いどこがわからん
const_castはsetの要素を変更するのに使う
>>630 そりゃまずいんじゃね?
木構造が壊れそうだが
>>629 const_castを使う主なケースは、糞なCのライブラリ関数の引数に
constな変数を渡すときだな。例を挙げるとこんな感じ。
void stupid_func(char *filename); // prototype
void Foo::some_method(const std::string& filename)
{
stupid_func(const_cast<char*>(filename.c_str()));
}
>>631 もちろん比較に影響及ぼすような変更はダメだぞ
構造体とかを入れたsetで、メンバの一つをキーに使ってるような場合があるだろう
そういう時にキー以外のメンバを変更するために使う
>>632 なるほど、ライブラリに渡すときなんかに使うのか
いくら糞でもライブラリ側を修正するわけにいかないもんな
volatile、組み込みでは見かけるがそれ以外では見かけたことがないんだが おまいらはvolatileってどんな時(除く組み込み用途)使っている? あと、const_castでvolatileを取るとる時ってどんな時?
>>633 俺はそういうのはmutableでやるなぁ。
const_castでやると、keyも含めて全て変更可能な「状態」になってしまうし。
>>583 aliceとかいう名前の開発ツールがたくさん入ってるから_
>>635 デバイスドライバを書く時には当然使う必要あるよね。
あとは、インラインアセンブリでローカル変数を上書きする時とか。
こんなことめったにやらないが。
>>636 mutableにすると、本当にキー以外もconstにしたいときに困るだろう
あくまでsetに入れたときの制約であって、そのためにmutableにするのは乱暴すぎる
キーがあるようなのはmapを使うなぁ setの要素を変更とかやったことないな 今度やってみるか
誰も答えてやらない
>>616 のために
Visual C++ Express Editionでぐぐれ
Visual C++ Express Editionを知った後にTurbo Cを使うなんて、、、地獄だ。。
>>638 ,
>>641 どうも、ほとんどアプリ系じゃ使わんということですな
>>641 の例じゃ普通はmutexやクリティカルセクション使うんじゃないの
それでvolatileを使うメリットがよく分らん,orz. コードが簡単になるがメリット?
Effective C++でconst_castはoperator[]の定義で使うことがあるみたいに書いてあったよね?
ttp://ritaz.blog64.fc2.com/blog-entry-66.html より引用。
class sample
{
public:
...;
const char& operator[](unsigned int position) const
{
...;
return dat[position];
}
char& operator[](unsigned int position)
{
return const_cast<char&>(static_cast<const sample&>(*this)[position]);
}
...;
};
>>645 blogにも書いてあるが、やりすぎな工夫の一例だな
>>644 どちらかというと、そういう排他制御の仕組みを自分で作るときに使う。
例えば下のコードをコンパイラが最適化した結果、
ロック確保する前や解放した後にhogeへ読み書きするコードが生成されたらシャレにならない。
MS仕様では、volatileなデータに読み書きするとそこを境界として、それより前後に読み書き処理が
ずらされないように最適化を抑えると言っている。
void f(hoge_t* hoge) //hogeを使うには排他制御でロックが必要とする
{
// ...
ロック確保
hogeを使う
ロック解放
// ...
}
>ロック確保する前や解放した後にhogeへ読み書きするコードが生成されたらシャレにならない。 意味が分からん。 最適化によって、「hogeを使う」に相当するコードが、「ロック確保」の前や「ロック解放」の後に配置されたらシャレにならないってこと?
>>648 ああ、ごめん。そういうこと。
携帯から打つのが面倒でいろいろ略した。
>>644 そういう用途にも使えるってだけでWindowsでもマルチスレッドでvolatileなんて使わない
mutexなりクリティカルセクションなりInterlocked-系関数なり使えばそこでフェンス張られるし
(Interlocked-系関数でvolatile使われてるけどね。間接的には使うことになるのかな)
やっぱり組み込みとかドライバ以外で使うことはないと思うな
>>647 ,
>>652 どうも、どうも
>>647 >そういう排他制御の仕組みを自分で作るときに使う
ずばり、自分でそういう仕組みは作ることないです
654 :
645 :2009/05/31(日) 20:04:50
>>651 忘れた。
原著第3版に書いてあった。
確か、最初の方の章に。
改訂2版にはどこにも書いていないんだが、 第3版には本当に書いてあるのか? 第4版まであと2年はかかりそうな気がするし、 第3版買ってくるか・・・
656 :
645 :2009/05/31(日) 21:28:28
>>655 第3版には本当に書いてある。
厳密に同じコードかどうが覚えてないが、
const版をnon-const版にて呼び出してconst_castでconst属性を外す
という方式であることは本当。
俺もそんなことして良いの!?と思ったから信じられなくても無理はない。
657 :
645 :2009/05/31(日) 21:31:01
わざわざ引っ張ってきて確かめみた。 原著第3版(日本語翻訳されているもの)で 15ページから始まる項目にある。
2版の21項「使えるときは、必ずconstを使おう」に 対応するんじゃないかなと思うけど、 そこではmutableをサポートしてないコンパイラのための苦肉の策として 「みっともないけど」と前置きした上でconst外しをしている。 これのことじゃないよな?
>>658 じゃないってば。
少しは俺を信じろ(笑)
他の人も誰か証言してくれ。
ああ、これって王家の血を引く者にしか読めないよ
663 :
645 :2009/05/31(日) 22:12:21
>>660 メンバ関数foo()のconst版とnon-const版の定義が
同じようなものになることは多々あるじゃない。
同じような定義を繰り返し書きたくない、そんなあなたにconst_cast
って言うような主旨。
const版をうまく定義することで、non-const版の定義は
それを呼び出してconst性を除去するだけ
で良くなる。
>>661 俺読めたw
・・・そろそろ天の啓示が来る頃だろうか。
>>664 もしかして、お兄様なの!
こんなところで巡り合えるなんて。。
おまえか しょせん、暇をもてあました神々の遊び
理解した。解説thx 感覚的にconst側で非constのコードを 再利用したくなりそうなものだけど それも理由があるのかな。 とりあえず第3版買ってくるよ。 生き別れた妹はいなかった気がするし。
668 :
645 :2009/05/31(日) 22:23:19
>>667 俺もそう思ったが、
理由としては
const側で非constメンバ関数を呼び出すというのはダメ
ってことらしい。
たとえ実際にはオブジェクトが変更されないとしても。
まあ買ってくる価値はあるかと。
何てったって名著だし、無駄な出費ではないと思う。
669 :
デフォルトの名無しさん :2009/05/31(日) 22:41:23
#define UNICODE #define _UNICODE で定義されたソースコードがあるとします。 それを #define UNICODE #define _UNICODE と定義してはエラーになってしまう、つまりANSI版のソースに混ぜて使いたい場合どの ようにすればいいのでしょうか? たとえば int WINAPI WinMain(…){ …(ANSIソースコード) sub(); } int sub(){ #define UNICODE #define _UNICODE …(UNICODEソースコード) } みたいなことはできるでしょうか?
できます。
いまいち質問内容がよく分からんが、 #define UNICODE #define _UNICODE したあと #undef UNICODE #undef _UNICODE すればdefineは消える。 でもWIN32なら、 UNICODE版、ANSI版両方そろってるはずだが。
CreateWindow("aaa",.... とかやってるんだろ
673 :
デフォルトの名無しさん :2009/05/31(日) 23:59:32
>>670 >>671 いやできなかった
結論からいうと
原理からいうとその方法でできるのは確かなんだが
UNICODEと_UNICODEは最初の最初で定義しておかなければならならないみたいだ
先にwindows.hとか読み込まれてるからその関係で動作がおかしくなる
>>672 アホすぎ
てか解決法をいうと単純にソースファイルをわければ解決できる
最初からやればよかったけど
本筋とは全く関係ないが、
>>669 を見ると_tWinMainにしろと言いたくなる。
もうこれから書くコードは全部_UNICODEでいいかもと思ってしまうがな。
なに、いいってことよ┏( ^ω^)┛
下の様な感じで合成関数を作ろうと思ったのですが、 error C2678: 二項演算子 '*' : 型 'composite_impl<result_type_,arg_type_>' の左オペランドを扱う演算子が見つかりません とエラーが出ます。どうやって回避すればいいのでしょうか?
struct composite_type{}; template<typename result_type_, typename arg_type_> struct composite_impl{ typedef result_type_ result_type; typedef arg_type_ arg_type; typedef result_type (*fn_type)(arg_type); static fn_type &fn_holder(){ static fn_type fn; return fn; } result_type operator ()(arg_type a) const{ return (fn_holder())(a); } }; template<typename result_type_a_, typename result_type_b_, typename arg_type_b_> struct composite_impl<result_type_a_, composite_impl<result_type_b_, arg_type_b_> >{ typedef result_type_a_ result_type; typedef arg_type_b_ arg_type; typedef result_type (*fn_type)(arg_type); static fn_type &fn_holder(){ static fn_type fn; return fn; } result_type operator ()(arg_type a) const{ return (fn_holder())(composite_impl<result_type_b, arg_type_b_>()(a)); } }; template<typename result_type, typename arg_type> inline composite_impl<result_type, arg_type> operator *(composite_type, result_type (*fn)(arg_type)){ composite_impl<result_type, arg_type> a; a.fn_holder() = fn; return a; } template<typename result_type_a, typename result_type_b, typename arg_type_b> inline composite_impl<result_type_a, composite_impl<result_type_b, arg_type_b> > operator *(composite_impl<result_type_a, result_type_b> a, result_type_b (*fn)(arg_type_b)){ composite_impl<result_type_a, composite_impl<result_type_b, arg_type_b> > a; a.fn_holder() = fn; return a; } composite_type composite; #include <iostream> #include <cstring> int fn_a(int a){ return a * a; } char *fn_b(int a){ static char str[0xFF]; std::sprintf(str, "%d", a + 1); return str; } int main(){ std::cout << (composite * fn_a * fn_b)(2) << std::endl; return 0; }
>>668 > const側で非constメンバ関数を呼び出すというのはダメ
> ってことらしい。
これって、単純にconstメンバ関数内で非constメンバ関数を呼び出すと
コンパイルが通らないって話。
>>679 const_castで*thisからconstを外すって話だよ。
>>680 あーそういうことね。
でも*thisのconst外しが駄目なのも当たり前の話だな。
*thisのconstは外してないぜ むしろconstメンバ関数を呼ぶために*thisにconstを付けてる 外してるのは戻り値のconst
???
>>645 のことだろ?
static_cast<const sample&>(*this)は明らかに*thisにconstを付けてる
何か間違ってるのか
なるほど理解した
ご、誤爆・・・
どんまい、 というかハードとソフト両方いけるとかうらやましい
>>687 全然 なんだかわからないwww
すごいな。
とりあえずイミフだからストリッパーってあたりに反応しとこうぜ
ストリッパーくらい分かるだろ 線の被覆を剥ぐための工具だろ
struct A{A();virtual void fun() = 0;}; struct B:A{B();fun();}; struct C{C(A&b); C problem(A&b);}; C c(B()); c.problem(B()); // no-match function になるのは何故? C::problem(一時オブジェクト参照)を弾くならコンストラクタでも弾くべきだと思うんだけど
ドラクエなどで登場する戦士や魔法使いを意味するFighterクラスと Mageクラスがあったとして、 そのクラスのインスタンスが持つHPやMP,攻撃力などのステータス一覧を表示する関数を作るとき、 クラス自信にその関数を持たせるのか、あるいはクラスとは関係のない部分で作るのか、どちらがいいんでしょう? クラス設計の考え方がまったくわかりません・・。
>>695 その場合はカプセル化を優先する。
まず、HPやMP,攻撃力などのステータスを格納する変数(intだったりstd::size_tだったりするだろう)のアクセス指定子がどう宣言されているかによって考えを分ける。
1.
もしprivateで宣言されていて、そのステータスをpublicなメンバ関数h_point()で取得するような仕組みにしている場合(むろんそれが望ましい)は、「クラスとは関係のない部分で作る」が正解。
つまり別の関数show_status(〜)を作り、〜の部分にキャラクタのインスタンスを渡すようにする。
2.
もしpublicで宣言されているならば、「クラス自身にその関数を持たせる」ないし「friend指定して外部関数を作る」が正解。しかしステータスを格納する変数がpublic指定されていること自体、そもそも望ましくないことだが。
>>693 そのコンストラクタで本当に動くか試した?
C c(B()); は C c(B (*)()); という関数宣言に解釈される。 B b0; C c(b0); c.problem(b0); とするとできましたが。 関数の引数のリファレンスの型にconstをつけて "const B&b"、"const A&b"のようにすると C c = C(B()); c.problem(B()); でもいけました。 なぜかは僕には分かりませんのでどなたか解説お願いします。 コンパイラはgcc4.2.1で確かめました。
const参照型のインスタンスは、呼び出す側が値渡しと同じ感覚で扱えるように、 一次オブジェクトで初期化できることになっている。
701 :
693 :2009/06/02(火) 20:13:27
実コードはstruct Bにtemplate特殊化やらvirtualメンバやらなんやら絡んで魔窟状態で実は
C c(static_cacst<A&>(B())); に成ってますた。
>>699 C c((B())); でも逝けますね。
>>701 Effective STL の第1章第6項「C++の最も奇妙な解析に注意しよう」に書かれてるね。
(この本自体はSTLの解説本だけど…)
でも、すべてのコンパイラで成功するとも書かれていない・・・おそろしや。
703 :
デフォルトの名無しさん :2009/06/03(水) 17:16:04
#include <stdio.h> void main(void) { char data[3465300] int idata[3465300]; int KOTAE[3465300/2]; int data1[12032/2][300]; int idata1[300][300]; int i,j,id,a,b,No,day,LDAY,d; char fnamein,fnameout; FILE *fin,*fout; #define LDAY 30 //月ごとに変える //No=1→ステータス;No=2→交通量;No3=速度;No4=オキュパンシー #define No 2 for(day=0;day<LDAY;day++){ d=day+1; printf("%d/%d\n",d,LDAY); sprintf(fnamein,"D:\\/torakan-Y/R_barashi/Ku0409/Ku0409%02d.dat",d); sprintf(fnameout,"D:\\/torakan-Y/R_barashi/Ku04/Q_Ku0409%02d.txt",d); fin = fopen(fnamein,"rb"); fread(&data,1,3465216,fin); fclose(fin); if((fout=fopen(fnameout,"w"))==NULL) printf("Cannot open output file\n");
705 :
703 :2009/06/03(水) 17:19:00
703のプログラムですが、コンパイルは通る一方で 出力される結果が同じ数字の繰り返しになってしまいます。 エラーの原因としては、以下の4行が怪しいと思っています。 詳しい方、よろしくお願いします。 sprintf(fnameout,"D:\\/torakan-Y/R_barashi/Ku04/Q_Ku0409%02d.txt",d); fin = fopen(fnamein,"rb"); fread(&data,1,3465216,fin); fclose(fin);
>>705 あんたが勝手に”エラー”って呼んでいるものを,具体的に書き表してごらんよ
少なくとも”出力される結果が同じ数字の繰り返し”になることは具体的に書け
変数宣言で嫌になるものは久しぶり…
スレの住人の中におエスパー様はおられませんか?
>>703 とりあえず変数を#defineで上書きしているのが分かった
710 :
703 :2009/06/03(水) 17:42:02
≫>705様 レスありがとうございます。 出力されたファイルを開くと 526855268552685といった感じで同じ数列がただ繰り返されたファイルが 出力されます。 このプログラムはもともと、膨大なデータの中から 一部分を抽出するプログラムとなっています。 また、その莫大なデータにはそのような数列は見られないので 勝手にエラーと判定してしまいました。 >709様 ありがとうございます。 さっそく そこを修正したいと思います。
>>710 かんじんのファイルに出力している部分が・・・ねぇwwwwwwさすがにESPじゃない俺にはむり
712 :
703 :2009/06/03(水) 17:57:36
for(i=0;i<3465216;i++){ idata[i]=int(data[i]); if(idata[i]<0){ idata[i]=256+idata[i]; } } id=0; for(i=0;i<3465216;i=i+2){ a=idata[i]/16; b=idata[i]%16; KOTAE[id]=a*16*16*16+b*16*16+idata[i+1]; id=id+1; } id=0; for(j=0;j<288;j++){ for(i=0;i<12032/2;i++){ data1[i][j]=KOTAE[id]; id=id+1; } }
713 :
703 :2009/06/03(水) 18:00:29
/*区間データの抜き出し*/ id=0; //////6号三郷JCT‐江戸橋JCT間//////////// for(j=0;j<288;j++){ for(i=0;i<17;i++){ idata1[id][j]=data1[4*i+(8+4*501+No-1)][j]; id=id+1; } id=0; } for(j=0;j<288;j++){ for(i=0;i<2;i++){ idata1[id+17][j]=data1[4*i+(8+4*772+No-1)][j]; id=id+1; } id=0; }
714 :
703 :2009/06/03(水) 18:02:01
for(j=0;j<288;j++){ for(i=0;i<15;i++){ idata1[id+19][j]=data1[4*i+(8+4*542+No-1)][j]; id=id+1; } id=0; } for(j=0;j<288;j++){ for(i=0;i<34;i++){ fprintf(fout,"%d",idata1[i][j]); } fprintf(fout,"\n"); } } }
>>712 > for(j=0;j<288;j++){
> for(i=0;i<12032/2;i++){
この辺で悪意を感じた
あと,もし仮に名前を付け替えるのが許可されているなら,ぜひデータ構造と名前を変えるべきだとおもふ
まずマジックナンバーが多過ぎるから定数で宣言して分かりやすい名前を付けるべき それと、 >char fnamein,fnameout; ここはファイル名格納するバッファじゃなかろうか
717 :
703 :2009/06/03(水) 18:11:01
>712 すいません。まったく悪意はないです。 もうしわけないです。 名前は変更できます。
そもそも何の目的で作られた何をするためのプログラムで どうなれば成功なんだよ そこが分からないのに何も答えられるわけがないだろ どうせ宿題なんだろうけど
720 :
703 :2009/06/03(水) 18:26:59
>719様 説明不足ですいません。 トラカンデータといわれる交通量や平均速度といった 情報が網羅されているデータから 一部分を抽出して、自分たちが調べたい路線の 交通量を抜き取るプログラムです。 数列が同じ数字の繰り返しにならなければ、ほぼ成功だと思います。 宿題ではないです。申し訳ないです。 >718様 さっそく、張ってみようと思います。
721 :
703 :2009/06/03(水) 18:30:03
ふむふむ ひどすぎて目眩がしてきた 一つ言えるのは、これはCであってC++ではないということだ だからスレ違い
と思ったらnew使ってるからC++かよ なんだこれは
読むのに時間かかりそうだ…
管理番号とかファイルのパスとか 危険な香りのする文字列がたくさんあるけど大丈夫なのか
>>703 とりあえず
fread(&data,1,3465216,fin);
↓
fread(data,1,3465216,fin);
プログラムに間違いらしきものはなし。 データ解析部分でデータの構造が合致していないような感じだが?
728 :
703 :2009/06/03(水) 19:18:54
>726様 あなたは神様です。 あなたのおかげで無事解決しました。 なんてお礼をいえばいいのかわかりません。
すげえうれしくない感謝の言葉だなぁ
You are God. I solved the problem, thank you. What it only has to say the reward is not understood.
731 :
703 :2009/06/03(水) 20:27:36
と思ったら、まだ解決していませんでした。 申し訳ないです。
<stdexcept> と <exception> って、 どっちをインクルードするほうが望ましいの?
<stdexcept>で定義されている例外を使いたければ<stdexcept>
>>731 書き直してもいい?
要するにファイルの内容は unsigned short 型のデータが
ビッグエンディアンで 6016x288 個格納されているのを
data1 に代入すれば data も idata も KOTAE も必要ないよね
>>703 社内で使ってる(であろう)コードをこんなところに晒して、
ただで済むと思ってるのか?
オープンソースじゃないだろうし、上司に知られたらやばいんじゃねーの。
スタックオーバーフローエラーを直してくれた先輩には もう見限られたのか?
ほんとプロが作るソースって ゴミクズだよな。 どこもかわらねえなぁ。
え?
>>703 の話なら、プロのコードじゃないっしょ。
社内でコンピュータにちょっと詳しい人(事務職とかバイトのお兄ちゃんとか)に
アホ課長が「エクセルで計算するのめんどいからお前プログラム書けよ」って
仕方なくしこったんじゃない?
どうみてもCで書いたコードを、その人がやめちゃって保守要員がいなくなったので
これまたその辺のちょっとコンピュータ詳しい奴にむりくりやらせてるってところでは。
すごいエスパー。昔、エスパドリューはエスパーが身につける特別な装備だと思っていたのを思い出した。
ふと思ったんだが↓↓ C++では関数が返せる変数の型は1つだけである。 (その型と継承関係によってはその子クラスの型でも返せることもあるが。) ところが、例外処理におけるthrowは関数から外へ任意の型の例外を投げることが可能である。 これをその関数の返り値(戻り値)とみなして プログラミングをするという面白い技法が この世に存在していてもおかしくないのではないか と思ったのだが、誰か知っている人いない? 例外を使ったプログラミングの話をしている訳じゃ無くて あくまでthrowによる例外を戻り値として利用するスタイルってことで。
テンプレートクラスを使えば戻り値の型なんて自由自在ですよ。 無茶しないでください。
そのアイデアに「catchされなければ呼出元へ伝播する」という例外の特徴も考慮した? していないならboost::any返せばいいでしょという話だと思う。
>>740 実用してる奴がいたら絶対に近づきたくないが
ネタとしてはおもしろそうだな。
はたして意味のあるプログラムを作ることができるのか・・・
もしうまいことやったとしても、Schemeなんかの継続のきわめて限定的なまねごとになるのではと思う。 どういう形か想像もつかないが。
継続ねえ。 じゃあお題は例外でC#で言うところのyield()を作る でどうよ。
_ さっそく自分で否定しちまった・・・
variantでいいじゃん 戻り値の型として使いたいものの集合がコンパイル時に決まっていないと 例外使う方法も結局何もできないわけだし
変態プログラミングの可能性と聞いて
750 :
703 :2009/06/04(木) 02:02:54
>734様 先程、プログラミングを回してみた結果 無事解決しました。 727様のおっしゃるとおり データ解析部分でデータの構造が合致してないことが 原因でした。 もし、お時間があるなら、書き直してくださったプログラムを 見せていただきたいです。
>>740 そういうのはイベント駆動型とかいうやつじゃないか
752 :
740 :2009/06/04(木) 06:28:37
>>741 え?
どういうことだい?
よく分からないんだが。。。
みんなありがとう。
俺も絶対やらないと思うけど、
>そのアイデアに「catchされなければ呼出元へ伝播する」という例外の特徴も考慮した?
一応考えてる。
boost::anyやvariantは頭をよぎったが忘れることにした。
うーん、むずかしいよねぇ。
少なくとも俺はやらないけど、きっと誰かが何かすごいことを
やってくれるんじゃないかと思った。
やらないのかよ
>>752 c#でもやっていてください
とくにLINQ
>>752 例外のキャッチってコストかかるんでパフォーマンス劣化が激しいと思うぞ
756 :
デフォルトの名無しさん :2009/06/04(木) 14:02:25
アゲ
757 :
732 :2009/06/04(木) 17:05:22
>>740 むやみやたらにthrow使うのはgotoと大して変わらないので、
普通やらん。
やめとけ。
普通に関数オブジェクトでも引数として渡せばいいだけやん。
760 :
740 :2009/06/04(木) 17:57:29
もちろん俺だって普通はやらんさ。 でもまあどこかの変態級のプログラマがうまくこれを生かして…(ry
試しに #define return assert(0) して、throw以外で関数から出るのを禁止してプログラム書いてみたらいい 何かが見えてくるかもしれんぞ
C++の関数を全部こう書き換える retType func(/* ... */){ /* ... */ return foo; } ↓ function func(/* ... */) throw(retType){ /* ... */ throw foo; } そして class function{private:function();~function();}; と定義すれば、めでたく例外指向プログラミング言語の出来上がり 使うのは遠慮します
763 :
740 :2009/06/04(木) 21:00:49
三値論理の関数型言語?で似たような事が出来たような? よくわからんが
boost::any を使えば受け取る側は関数側から何が返ってくるか知らなくてもいいけど 例外の場合は、帰ってくる型が何であるかは知っておく必要があるよね? 間違ってるかしら・・・
>>765 一応catch(...)で、何でも受けれる。
受けられるだけだが。
戻り値返しにない例外の機能として、
安全な中間すっとばしがある。
funcA() -> funcB() -> funcC() -> 例外発生
↑-----------------------------」
これを使えば、非常に柔軟な逆フロー制御が実現できる。
つまり、メインルーチンを例外のcatch()ブロックに書くのだ。
これを使って何が出来るかというと、それは次の人どうぞ。
一方ロシアはgotoを使った。
anyだろうと何だろうと型を知らないと何も出来ないから、 結局そのままどっかに転送するしかないよな throw;で同じ事が出来そうな気はする
VC9だと落ちるんだけどw #include <iostream> void fib(int n) { if (n < 2) { throw 1; } else { try { fib(n-1); } catch (int r1) { try { fib(n-2); } catch (int r2) { throw r1 + r2; } } } } int main() { try { fib(20); } catch (int ret) { std::cout << ret << std::endl; } return 0; }
あーそうだ、多重例外は未定義だったな 標準C++の範囲で例外指向プログラミングはできないようです
うーん、 変態Chain Respinsibility? void discover() { switch (random) { case 0: throw Chair; case 1: throw Human; case 2: throw Orange; case 3: throw Truth; } } void loop() { while (1) { Sitter(Killer(Eater(Philosopher(discover)))); } } どうすんだこれ・・・
綴りひでぇorz
いいかんじに変態的だな
多重例外って何ですか? アクティブな例外が2つ以上同時に発生することですか? それともtry・catchブロックの中にtry・catchブロックがあることですか?
例外ハンドラで例外が出ること
テンプレートクラスで自身を返す場合、書き方としてどっちが正しいのでしょうか。 1も正しいなら今後1で書こうと思ってます。 template<class T> class X { public: X &Func() // 1 X<T> &Func() // 2 { return *this; } }
778 :
デフォルトの名無しさん :2009/06/05(金) 11:33:33
C++を1から学習しようかと思うのですが、参考書は何がおすすめでしょうか? visual C++を使おうかと思っているのですが。 分厚くてもよいので、一冊で応用まで深く学習出来るのはありませんかね?
>>777 2、テンプレート引数を省略しないといけないのはコンストラクタだけ
781 :
デフォルトの名無しさん :2009/06/05(金) 13:44:02
softbank
そういう時に真っ先に「C++ 禿本」で検索しない精神がよくわからん。
784 :
デフォルトの名無しさん :2009/06/05(金) 14:47:44
検索したのですが、出てきませんでした。 ていうより、59件ヒットしてその全てがただ禿本とC++を含んでるやつのみで 何の略かも書いてありませんでした。 その本の正式名称がわかりません。 すいませんが、本の正式名称で書いていただけませんか?
C++ 禿 でぐぐったら一番上におっさんの名前出てきたわw
786 :
780 :2009/06/05(金) 15:04:39
確かにC++ってググるときに引用符を付けないと駄目なんだよな。
正式名称はThe C Programming Language(邦訳はプログラミング言語C++)
著者はC++の設計者である禿ことBjarne Stroustrupだ。
http://www.research.att.com/~bs/ に写真があるからよく拝んでおくように。
日本語訳については色々言われているみたいだが、俺は原著しか使ったことが
ないので分からん。英語に問題ないなら原著をすすめておく。
一番、二番目に出てくるならまだしもそれ以外でググレとか言う奴の精神が分からん。 素直に教えて感謝されればいいのに
788 :
デフォルトの名無しさん :2009/06/05(金) 15:12:09
>>786 禿本とはそういう意味だったのですか。
教えてくださってどうもありがとうございました。参考にします。
確かに"禿本"だけであとググれってのはちょっとひどいなw 英語に問題ないならTC++PL(禿本)よりも先にProgrammingを読んだほうがいいかも 同じようなこと書いてあるけどProgrammingのほうが分かりやすい TC++PLにしか書いてないこともあるからどのみちTC++PLは読むんだけどね
791 :
780 :2009/06/05(金) 15:42:31
>>876 自己レススマソ。原著名間違えた。K&Rじゃないっての。
>>787 まあ2chだから仕方ないね。
禿本ってこのスレでは良く知られてると思ってたけど、意外とそうでもないのかな。
792 :
777 :2009/06/05(金) 15:44:42
>>779 ありがとう。コンパイル通るからいいのかと思ったけど
やっぱり基本的には全部書かないとだめなのね。
禿本と書いてても意味がわからんからスルーしてた スルーで正解だった
>>787 > 一番、二番目に出てくるならまだしも
Googleを使わせるか否かを考えるのに「一番、二番目に出て来るかどうか」を基準にする、
怠惰な人間をつけあがらせる使命でもあるかのような考え方は理解不能だし、
悪いけど二番目の結果(環境依存OKスレの2スレ目)にこういう文章が出て来るぞ。
> 「プログラミング言語C++」は禿本と呼ぶ。
あ、"C++"と"禿本"をダブルクォーテーションで括る発想に至らないバカは考慮してないけど。
質問です。どうしてこのスレには捻くれた奴が湧くんですか?
たとえばどのレスのことなのか例を挙げてくれないと、 本当にそういう傾向があるのか、自分のバカさを指摘されたバカが 必死にそう見ようとしてるだけなのか判断つかず、回答できないです。
>>792 2でもいいんだけどね。テンプレートパラメータは
宣言された範囲(テンプレートのスコープ)内では省略していいことになっている。
クラス定義の冒頭で template が宣言されていて、その範囲内に入っているので、
この場合のメンバ関数宣言のテンプレートパラメータは省略できる。
(Accelerated C++ p.197などを参照)
template < class T > class foo {
template < class T > foo &bar( foo<T> &t );
};
のような紛らわしい宣言も可能な様子。
>>795 捻くれものは大抵、過去に何らかの形で虐げられた経験がある
あとはわかるな?
>795 C++自体が捻れた言語だからです。
>>797 全然別人なんだけど割り込んで聞いて良い?
template < class T > class foo {
template < class T > foo &bar( foo<T> &t );
};
ってのは要するに
template < class T > class foo {
template < class U > foo<T> &bar( foo<U> &t );
};
ってことだよね?
>>798 わかります。
現実の現在で叩きのめされたので、架空の過去を夢想して脳内逆襲ですね?
>>800 最初の方はgcc 4.2.1ではエラーになった。
(・3・) エェー。ぼじゅあるくっぷぷ(Visual C++)では問題なしだYO
>>800 Yes。
以下の変態プログラムでテンプレートパラメータの挙動についてご確認ください #include <iostream> using namespace std; template < class T > class foo { public: foo() : x( 0 ) {}; foo( foo *p ) : x( p ) {}; template < class T > foo &bar( foo<T> &t ){ cout << t.member << endl; return *x; } T member; foo *x; }; int main() { foo< int > base; base.member = 1000; foo< int > i(&base); foo< char > c; i.member = 1; c.member = 'a'; foo< int > r = i.bar( c ); cout << r.member << endl; }
危うく騙されそうになったが return *xだから挙動自体は普通だな
r.memberが初期化されない…と思ったがコピーコンストラクタじゃないのか。
>>804 読むだけで疲労した。
barメンバ関数が何をやりたいのか意図が分からない
(練習プログラムだから仕方ないことだが。)
のに理解をじゃまされた。
分かって良かった。
809 :
807 :2009/06/07(日) 12:56:34
>>808 ああそうなのか、ここのところこのスレ見てなかったから
全然流れを読んでなかったわ。
下のように、クラスAAのインスタンスを、メモリーに割り当てたときに。 コンストラクタとデストラクタをどうやって起動したらいいのでしょ? class AA { int i1,i2; AA(); ~AA(); } void func() { char dat[100]; AA *dat; dat = (AA *)dat; }
コンストラクタ new(dat) AA(); デストラクタ dat->~AA();
AA * dat = new AA[100]; delete[] dat;
上の例、バッファーとポインターが同じでした、ミスすみません
>>881 下記のようにうにエラーになります
>>812 100個のインスタンスを作るわけではないです
class AA
{
int a1,a2;
public:
AA() { printf("AA コンストラクタ\n"); }
~AA() { printf("AA デストラクタ\n"); }
};
int _tmain(int argc, _TCHAR* argv[])
{
char buf[100];
AA *datp;
datp = (AA *)buf;
new(datp) AA(); // ここがエラーになる…
datp->~AA();
return 0;
}
エラー 1 error C2660: 'operator new' : 関数に 2 個の引数を指定できません。
#include <new> が抜けてるだろ
815 :
デフォルトの名無しさん :2009/06/07(日) 14:41:49
ローカル変数に対するplacement newって、アラインメントを気にする必要がなかったっけ?
気にする必要があると思います。 実際のプログラムは、sizeof で確認をしています
819 :
デフォルトの名無しさん :2009/06/07(日) 16:27:09
std::vector のようなコンテナを作ろうと思うんだが、 要件について詳しくまとまってるページない?
規格を読め
別にinterfaceクラスを継承してるわけでもないし、 要件なんて無いぞ。
要するに value_type なんかの必須 typedef や 領域確保時の用件とかを知りたいんじゃろ? 領域確保に new を使っちゃらめとか、 知らないとはまる部分もあるしー。
>>769-770 >>775-776 このレスで出てきている多重例外「例外ハンドラで例外が出ること」についてですが、
try
{foo();}//適当な例外を投げる関数
catch(const std::exception& ex)
{throw 42;}//ここが多重例外
ってことですよね?
では
try
{foo();}//適当な例外を投げる関数
catch(const std::exception& ex)
{throw ex;}//ここは?
この様に例外を再送する場合も多重例外となり未定義の動作ですか?
また、再送する場合{throw;}と書いても未定義になりますか?
>>826 >770や>776は何か勘違いしているような・・・。
例外ハンドラ(catch節)で例外を投げるのは正当。
多重例外というのはもっと異常な事態で、
例外によるスタックの巻戻し中にデストラクタがさらに例外を投げたとか、
値渡しのcatchへ例外をコピー中にコピーコンストラクタが例外を投げたとかのことを言い、
そういう時でも未定義ではなく、terminate()が呼ばれるんじゃなかったっけ?
とりあえず例外の再送出は問題ないと分かれば当面は解決です。ありがとうございます。
>>827 >例外によるスタックの巻戻し中にデストラクタがさらに例外を投げた
は、
私(
>>775 )の言う
>アクティブな例外が2つ以上同時に発生すること
ってヤツですよね。
この場合は未定義だとEffective C++で紹介されています。
しかし
デストラクタからの例外送出::実装技術
ttp://cppemb.blog17.fc2.com/blog-entry-31.html ここによると
>デストラクタから例外を送出するクラスAのオブジェクトを自動記憶域で宣言し、
>その生存期間内で他の例外が発生した場合、A::~A()が呼び出されて、
>その中でまた例外が送出されます。これは二重例外と呼ばれ、
>問答無用でstd::teminateが呼び出されます。
>次に、デストラクタから例外を送出するかもしれないオブジェクトを
>静的記憶域期間で宣言した場合を考えてみてください。
>静的記憶域のオブジェクトを監視ブロック(try〜catchの制御文)で囲む構文を
>記述することはできません。すなわち、こちらはデストラクタから例外が発生した
>時点で(std::terminateの呼び出しではなく)未定義の動作になります。
と書いてありますが、果たして何がどうなんでしょうね。
catch節で例外を受けた場合、受け取った例外を再送するか、 受け取った例外を破棄して別の例外を送出するしかなくて、 結局、伝播する例外は1つだけになるので問題ない。 それ以外で例外伝播中に他の例外が発生すると、 2つの例外を伝播させなければならなくなるけど、 それはできないことになってて、かわりにstd::terminate()が呼ばれる。
830 :
828 :2009/06/07(日) 22:14:01
多重例外が未定義動作だなんてどこに書いてあった?
デストラクタで例外を投げてもちゃんと動作は定義されている 意味のある(まともな)動作をさせるのが困難というだけ
833 :
828 :2009/06/08(月) 06:59:07
>>831 Effective C++ 原著第3版
p39末行
〜p40頭の数行
にかけて、はっきりと未定義と書かれています。
>>832 それもEffective C++で上と同じ節に書いてあります。
>>830 静的記憶域期間を持つオブジェクトがデストラクタで例外送出したらterminateじゃなかったっけ
と思ったら「staticでnon-local」はterminateらしい
「staticでlocal」は記述が見当たらねぇ…
835 :
828 :2009/06/08(月) 16:14:44
そしてまあ困ったことに、たしかVC2008とかの有名どころですら 複雑な例外処理の仕様は、正確には実装されていないと聞いたことがあります。 結局は多重例外になるという状況を作らないように気をつけていくしかないのでしょうかね。
837 :
828 :2009/06/08(月) 21:15:40
>>836 私は仕様書を持ってないんですよ。
趣味グラマなもんでして。
例外処理の実装を詳しく説明している書籍は何がありますか?
more exceptional C++
841 :
837 :2009/06/08(月) 21:58:59
>>840 ありがとうございます。
なんとかDLしたいものですが、ガードされているようですね。
必要に応じてWEBで見るようにします。
FDISでよければこことか
ttp://www.kuzbass.ru/docs/isocpp/ 15.5.1に
>when the exception handling mechanism,
>after completing evaluation of the expression to be thrown but before the exception is caught,
>calls a user function that exits via an uncaught exception,
>...
>In such cases, void terminate(); is called.
とあるから、terminate()が呼ばれるのは間違いないと思うのだが、
Effective C++には確かに未定義っぽいことが書いてあるし…
英語版でもそうなのかなあ
しかし、デストラクタで例外なげるようなプログラムなんて書く訳無いし、あんまり気にしすぎても仕方ないよ。 いえ、ごめんなさい。
関数テンプレートがインスタンスを指定することによって実体化できるのに対し、 クラステンプレートは型名を指定しないと実体化できないところに不便さを感じます(boost::rangeとか特に)。 何かいい方法はないですかね?
そのためのtypedefだろ?
クラステンプレートは、型を引数に取って型を返す関数
>>844 std::make_pairやboost::make_iterator_rangeのように関数テンプレートでラップすればいい。
>844 関数テンプレートもインスタンスで指定しているわけじゃないぜ。単に引数の型を推論しているだけ。 #動的な型は対応できない どうしてもというなら関数テンプレートでラッパー作ればよろし。
>>845 型指定するのが手間に思えます。型推論してくれないかなと。
>>846 関数の引数をテンプレートに変更してもそのまま使えるのに、クラスのメンバ変数をテンプレートにすると使う側に手間が増えるのが不便に感じます。
>>848 makeXXXの戻り値を受け取るところで結局型指定が必要になってしまいます。
>>849 書き方が悪かったです。
template<class T>
void F(T t);
template<class T>
class C {
T t_;
public:
C(T t):t_(t){}
};
F(hoge);// hogeを簡単に渡せる
C<Hoge> c(hoge);// 型を指定しないと渡せない
この違いを埋めることってできないですか?
rangeを渡す時、後者はめんどくさく感じて仕方ないです。
>>850 > F(hoge);// hogeを簡単に渡せる
> C<Hoge> c(hoge);// 型を指定しないと渡せない
どう書ければうれしいの?
>>851 Hogeを書かなくてよくなればうれしいです。
言語の仕様上、Cを非テンプレートクラスにするしかないですかね。
boost::any使っても値を取り出すことができないし、うーん・・・。
class B{public:virtual B&fn()=0;}; template<T>class A:B{public:T t_;A(T t);B&fn();}; class C{A&a;public:template<T>C(T t):a(C<T>(t)){};B&fn(){return a.fn();}}; 実現しようと思えば物凄く面倒。
>>852 つまりこういうこと?
C<> c(hoge);
>850 F(hoge)のhogeはどのみち静的な型になってるだろ。 C<Hoge>とするのに比べてそんなに汎用性が高くなっているわけじゃないよ。 型を推論してくれるから面倒なことは少ないけど。まあ、素直にC++0xのauto待ちでいいんじゃね?
>>853 頭がクラクラしてきます。
>>854 そのコードが許されれば大満足です。
>>855 単純に入力の手間の問題ですね。
boost::range使っていて、コードを書いてる時に型を意識しないといけないのはつまらないなーと思いました。
100万回呼ばれるメソッドがあったとして Hoge * f(...) Hoge & f(...) ってどっちがお得なのでしょうか?
コンパイラしだいだけど、大体、どっちもいっしょ。
100万回程度ならどっちも同じ。
呼び出しの時間なんて気にするなってことだろjk マイクロ秒で競ってどうするんだよ…
呼び出し側にも依るが、参照とポインタだけの違いならまったく同じバイトコードになる可能性が高い 参照なんてのは結局ただのポインタだからね
参照の場合はコンパイル時のチェックがかかるだけで、バイナリは同じものになるって話を聞いたことがあるが・・・ ホンマかいな
コンパイルの時間まで考慮するならHoge*f(...)の方が早くなる可能性があるな
>>863 絶対じゃないだろうが、その可能性はあるでしょうな。
参照はどう実装しても良いわけで、
別に参照はポインタを用いて実装されているという保証はない。
だが普通ポインタを用いて実装するので、。
TCP/IPのソケット通信プログラムなのですが connectを実行し、接続確認にsendとrecv を行っているのですが、recvでソケットエラー が発生し、GetLasterrorでエラーコード を取得すると「既に使われている(183)」でした。 何故こんなエラーになるのか分からず 困っています。どなたか教えて下さい。
環境がわからないし、エラーは正確に書くべき。
WSAGetLastError呼べよ
869 :
866 :2009/06/10(水) 19:33:58
>>867 送信先:Windows2003Server
送信元:WindowsXP
開発:VC2005
recv()の戻り値が-1
WSAGetLastErrorでエラーコードを取得したら
183だった。
ということですm(_ _)m
>>868 すまん、WSAGetLastError使ってた。
wineをみるとWSAGetLastErrorとGetLastErrorは同じものです。 recvのすぐ後でミューテックスをロック/アンロックなどを しているんではないですか?
class MyClass { protected: struct foo_t{ struct bar_t{ }foo; };
すみません。途中で書き込んでしまいました。 class MyClass { protected: enum {NUM = 5}; struct foo_t{ struct bar_t{ }bar[NUM]; }foo; }; VC6で上記コードをコンパイルすると、NUMにアクセスできないというエラーが出ます。 NUMをpublicで定義すると大丈夫です。 構造体の入れ子になった場合はpublicでないとアクセスできないのでしょうか? class MyClass { protected: enum {NUM = 5}; int foo[NUM]; }; ちなみにこちらは問題ありませんでした。
bar_tを外で宣言するか foo_tに適切なコンストラクタを用意すれば良い
gcc4.2.1なら大丈夫
レスありがとうございます。 fooはPOD型であってほしいので、コンストラクタを用意するのは望ましくないです。 後出しですみません。 bar_tを外で宣言するというのはどういうことでしょうか?
>>874 VC6なのでenumハックを使っています。
VC6なんて窓から投げ捨てろ
>>876 VC6はもうVC6言語だと思った方がいいくらい、標準と違う。
そんなクソ環境、捨ててしまえ。
eclipseとgccにすればっ
VCのお手軽感捨てたくなければ最新のExpressって手もあるな VC6はリソースの編集専用にすればよろし
全く持ってその通りなんですが、納品先がVC6で開発してるものでorz
納品先を捨ててしまえ!、え?、違うって(ry
publicにすればビルドできるのでそうしときます
gccってfriendつけないでも平気なんだ 知らなかった
今、双方向のリスト構造のテストプログラム組んで思ったんだけど int main{ // hpはノードのポインタ型 //--上・省略-- hp = hp->next; //--下・省略-- } っていう風にやったら普通にうまくいくんだけど、 これを関数かしてやって void gotoNextNode(Node* pnode){ pnode = pnode->next; } int main{ // hpはノードのポインタ型 //--上・省略-- gotoNextNode(hp); //--下・省略-- } ってやったら「pnode = pnode->next;」の部分が効かないみたいなんだけどなんでだろorz?
それは、ローカル変数に入れても、なにもならん
gotoNextNode(&hp);
888 :
885 :2009/06/11(木) 00:18:06
ノードのポインタ型は下のようになってて typedef struct _Node{ int num; struct _Node *next; struct _Node *back; }Node; ポインタ渡してるからいけるんじゃね?・・・って思ったんだけどさ
*pnode = pnode->next; じゃなくて?
890 :
885 :2009/06/11(木) 00:20:06
んで、hpはNode* hpで定義してます
void gotoNextNode(Node* &pnode){
C++ならポインタのリファレンスが使えるから gotoNextNode(Node*& pnode)
893 :
885 :2009/06/11(木) 00:27:08
うは、確かに*の横に&付けたらうまくいったわサンクスコ *&なんて使い方初めて知ったわ
void gotoNextNode(Node**pnode){ *pnode = (*pnode)->next; } 型 & hoge だから別に特殊なことやってる訳じゃないよ
なんで二重ポインタやポインタ+リファレンスを使わないといけないんだろう・・・? ポインタが仮想変数になったときにポインタじゃなくて値として扱われてしまうとか?
int i = 5; myFunc(i); void myFunc(int a) { a = 1; } ってやって、iの値が変わらないんだけど!って言ってるのと同じであることはわかった上で、 不満だと言っている?
単純に「ポインタで受け取れば引数の変更が呼び出し元に反映される」と考えてはいけない。
引数に対する変更が呼び出し元に反映されるためには、
変更したいものを指すポインタを受け取るとか、変更したいものを参照で受け取るとか
しないといけない。
>>855 の hp = hp->next; というコードは、ポインタの値を変更してるよね。
「変更したいもの」がポインタなんだ。
だから、ポインタのポインタとか、ポインタの参照を受け取らなければならない。
898 :
897 :2009/06/11(木) 01:48:37
void myFunc(int a) { a = 1; } の例はすぐに関数抜けた時点でaが開放されて値が消えるってのは分かるけど・・・ その例と同じってのは分かってないわ・・・スマン
typedefしたら分かりやすいか?
typedef Node* PNode;
PNode hp;
void gotoNextNode(PNode pnode){
pnode = pnode->next;
}
int main{
// 略
gotoNextNode(hp);
// 略
}
hpは変更されない。これはほぼ
>>896 と同じ。
受け取ったPNode値への変更が呼び出し元に反映されるには、PNode* や PNode& で受け取らないと。
int型の変数である、iの値を変更したい場合に、 int型を指すことができるポインタ(int*)、もしくは参照(int&)で受けなければならない というのはわかっているってことね? だったら、こう置き換えてみたら? Node*型の変数である、hpの値を変更したいのであれば Node*型を指すことができるポインタ(Node**)、もしくは参照(Node*&)で受けなければならない
あー、typedefで何を言いたいかって考えたらなんとなく分かってきたわ。 単にポインタで受け取る時は値を変更する時にも使うから、 それと同じ状態になって関数を抜けるから無効になってるということで ポインタを変更したいときはPNode* や PNode& で受け取らないといけないって感じでおk?
ポインタを代入したいから >895
>>902 まあ、そういう理解でおk。
typedefなんか持ち出して余計混乱させたらどうしようかと思ったが、たぶんちゃんと通じてると思う。
K&Rでは構造体をうまく使ってわかりにくいダブルポインタを回避していた C++ならイテレータクラスを作ってポインタのやり取りそのものを回避(中は結局ポインタだけど) ダブルポインタを使う時点でもしかしたら設計に問題が^^
pimplで使うスマートポインタって皆さんどうしてます? ディープコピー方式のoperator=を持つshared_ptrがあれば便利だと思うんですが、どうもなさそうです。
>>906 shared_ptrは浅いコピーだからこそpimplイディオムは生きるのだよ。
でもまあディープコピーにしたいこともあるのかもね。
ディープコピーにしたいってどんな状況?
class MyClass;
class MyClass_impl;
だとして、MyClassのコピーコンストラクタを適切に定義すれば
boost::shared_ptrで十分じゃないかと思うよ。
>>907 pimplイディオムを使わないでMyClassを実装した場合と同じ挙動にしたいです。
コピーコンストラクタやoperator=を書かない事(コンパイラまかせ)はよくあるので、
そういった場合にpimplで実装した事によって挙動が変わるのは嫌だなと思います。
pimpl使う版と使わない版のMyClassが必要で、その挙動を変えないためってこと? 何のためにそんなことするのかは知らないけど、同じようなクラス2つ書いてコード重複するくらいなら pimplなんか使わない方がいいよ
>>909 pimpl版と非pimpl版の2つがあるわけではないです。
pimplイディオムで実装することによって、注意しなければいけない事を増やしたくないという意味です。
MyClassのコピーコンストラクタやoperator=を書き忘れて(pimplじゃなければ書かなくてもOKだから忘れやすい)
バグが発生したりしないために自動でディープコピーになってくれた方が便利だと思います。
>910 boost::any使いなされ。あれは値のセマンティクスになってるよ。 >774みたいに突っ込むコンテナによってセマンティクスを変える手もあるけど。
912 :
907 :2009/06/11(木) 22:17:10
>>910 あー、言いたいこと分かった。
要は君自身、今のところは問題無くpimplイディオムを使えてはいるけど、
いつかうっかりしそうだからディープコピーなshared_ptrがあったら
いいなぁ
ってことだよね?
でも
>自動でディープコピーになってくれた方が便利だと思います。
いやいやそりゃ困るよ。
浅いコピーだからこそ生きるpimplイディオムの状況ってかなりあるのだよ。
例えばoperator=で浅いコピーにすることにより超高速なコピーが出来るわけ。
デフォでshallow copyで deep copyは明示的にclone()を使うっていう決まりを作るとか
デフォはdeep copyで shallow copyは明示的にdangerous_clone()を使う決まりの方がいいです
>>911 pimplにboost::anyを使うというのは初めて知りました。
確かに便利ですね。
弱点をあげるなら、速度が若干遅くなりそうなところでしょうか。
>>912 ,913
>>914 の方が私は直感的にわかりやすく感じます。
ありがとうございました。
直感的にわかりやすいかどうかよりも、間違いが起こりにくいという点で
>>914 の方がいいなあ。
間違えてデータ壊れるか、間違えて処理が遅いか、なら後者の方がいい
C++はヒープの無い環境でも使えるようになっていて、 組み込みでも実際使われている。 それをデフォでdeep copyなんかにされたらたまったものじゃない。
deep copyだとまずい理由がある時は明示的にshallowにすればいいじゃん。 deepで困るケースは少ないんだからデフォはdeepでOK。 つーかshallow copyによる高速化とpimpl関係なくない?たまたま一石二鳥になっているだけで。
そもそも、pimplで深いコピーにするのが不可能でも特別面倒でもないでしょ。 ほかのメンバ関数と同じ調子で、コピーコンストラクタとoperator =を定義するだけのはず。
だからコピーコンストラクタと代入演算子を定義し忘れるから Pimplはdeep copyをデフォにして欲しいと言ってんの もしかしてアフォ?
shallow copyをする気がないなら、そもそもshared_ptrにしなくていいのでは。 auto_ptrやscoped_ptrにすれば、コピーコンストラクタと代入演算子を定義し忘れることはない (定義し忘れるとコピーがコンパイルエラー)。
>>921 auto_ptrもscoped_ptrも不完全型には使えない。
ttp://d.hatena.ne.jp/Cryolite/20060108 (不完全型によるコンパイラファイアウォールとスマートポインタの両立(その1)以降を参照)
空のデストラクタを書くのも手間だし、コピーコンストラクタと代入演算子を書くのも手間。
deep copyにしたくてshared_ptrを使いたいなんて言ってるやつはいない。pimplにぴったりのスマートポインタないっていう話。
うーん。明示的にデストラクタ書かなきゃいけないのがそんなにデメリットだとは思ってなかったんだが まあ、気にする人も結構いるのか。
unique_ptrがoperator=でdeep copyしてくれればいいのに。
当然じゃねーの?てな部分に疑問を呈す
>>922 の様な人が声高に暴れて言語やライブラリのカオス度が濃くなるんだよな
科学技術とか未踏の分野の開拓なら役に立つかもしれんけど邪魔な存在だな
しかしpimpl_ptrは何回もrejectされている…
pimpl自体、きもいイディオムだから、あんなの使わなくて済むようななにかを追加して欲しい
何の話をしているのかいまいちわからないが ポインタ型があったとして A a, b; A *pa=&a, *pb=&b; pa = pb; こうしたら、aがbの値に上書きされるってこと? なんだがおかしいね。 *pa = *pb; だよね普通。
個人的にpimplを使うようなでかいクラスは大体コンストラクタとかも 全部ソースで定義するのでscoped_ptrで問題なし
ちょいとしつもんだんですが、 30,000x30,0000x4程度のbool配列と、30,000x30,0000のint配列を使いたいという思いでいっぱいです。 しかし単純に配列を作ってしまうと、やはりout of memoryです。 どうにかして要素数を減らすのが一番だとは思うんですが、 一般的に、このように膨大な要素の配列を扱わざるをえない場合にはどのような方法を用いるのでしょうか?
>>930 速度が滅茶苦茶遅くていいならファイルをメモリと見なし
operator[]をオーバーロードするとか
>ちょいとしつもんだんですが、 質問団?w そのくらいの量なら、64bitOSで普通にnewでもvectorでも持てると思うけど。 まぁ、swapされるのは覚悟する必要があるな。 処で、それ本当に必要なの? 疎行列として扱うとか、boolではなくcharかbitで保持するとかできない?
>>933 >64bitOSで普通に
さらっと、OSレベルで条件付け加えんなw
アフォか
>>934 2バイト整数を3万掛ける3万なら、32bitOSでも普通にOK。
今時、Windowsでも2GB位積んでるのが当たり前だしね。
> 30,000x30,0000x4程度のbool配列と、30,000x30,0000のint配列を使いたいという思いでいっぱいです。 30,0000?
うお、それは気づかなかった。30万なのか?w
2G程度あっても無駄無駄無駄ーなのです
ごめんなさい!3万x3万です!ちなみに768MBしか積んでません><クズです!
>>931-933 0or1のフラグとして使うつもりでboolを使いました。
やろうと思っていることは、「生物学で使うDNA塩基配列のアライメント」で
int 3マンx3マンを隅から数値を埋めていく一方で、
その数値を確認しながら条件に従って、その要素に対応するboolの配列の要素1-3に1or0を入れていく。
ということを行っています。
intの配列array[i][j]については[i+1][j+1]まで処理した時点で破棄できるのでもっと少なくできると思うんですが、
bool配列についてはすべて埋め終わった後に、もう一度フラグの確認をしていくのですべて残しておく必要があります。
ちなみにbool型が一番サイズが小さいと勝手に思い込んでいました。
なんだか良くわからないけど,計算用の鯖用意すれば解決するんじゃないかな^^;
パソコンでやるなら
>>933 とか.
でも
> int 3マンx3マンを隅から数値を埋めていく一方で、
> その数値を確認しながら条件に従って、その要素に対応するboolの配列の要素1-3に1or0を入れていく。
これって注意深く行うとすると,今状態[3万×3万]と次状態[3万×3万]が必要になるんじゃないかい?
軽くめんどくさい
int配列やbit配列の要素間で、相互参照がないなら ストレージに対して、逐次読み出し、逐次書き込みで いいんじゃねーの。
塩基配列なら AGTC の4種 30kx30k 900M 1bit データなら 900M/8 = 112MB 塩基配列なら4種2bit 900M/4 = 225MB メモリに載せるのは可能っぽい
>>939 768MBでも仮想記憶があるから屑だなんて言っちゃイヤ!
と言うのはさておいて。
>intの配列array[i][j]については[i+1][j+1]まで処理した時点で破棄できるのでもっと少なくできると思うんですが、
これは、相互参照があるってことなのかな?
だとしても、1行3万点として前後1行ずつで併せて3行がメモリにあれば事が足りるよね。
後は、ディスクをぶん回すことになるけどなんとかなりそうだ。
# 最初は1000x1000くらいに絞って作らないとデバッグの段階で死ねるね。
連続領域で取ることができないだけなので、int**にして3万を3万回動的確保すればいけるんじゃないの?
今メモリ安いのに。。。 768MB しかないと CPU も辛そうじゃね?
安物ネットブックでも1GBは積んでる時代だしな。
みなさんありがとおおO!!!!! bool → bit につめて、 array → 3行 にしたら、 なんとかなりそうです!!
なんとかなってるといいな
A案 MyClass hoge; for (…) { hoge = func(); … } B案 for (…) { MyClass hoge = func(); … } C案 { MyClass hoge; for (…) { hoge = func(); … } } あなたはどれ?
ほとんどAかなー 時々Bと同じスコープで宣言位置がforの中に入れてるときがある ただしjava
Aだなあ。 Cはわからなくもない(スコープ制限つけたかっただけだよね?) Bってコスト高くつかない?そうでもないのかな?
MyClassの大きさによるけど、大体C。 MyClassが小さいならB
おれは基本BでMyClassがでかければA。 ただこの例くらいなら気の利いた最適化してくれてコスト気にする必要はなさそうな気もするな。
B以外は池沼
普通に大きいだけならコストA>BはあってもB<Aはありえん。 B一択。jk
ここには書いてないが MyClass のデストラクタは処理に1000時間かかるんだよね。
これまた書いていないんだがコピー演算子には ブラジルに電話をかける処理が含まれているんだ。
けどコピーコンストラクタは超速いんだ
なぁにstaticにすればもんだいない
ループ中にfunc()の戻り値が変化するならB、しないならA
struct{ MyClass&hoge; unsigned begin,end; operator X(){for (…) {hoge = func();…};return X;} }OBJ={hoge,BEGIN,END}; return OBJ;
>>960 言ってることおかしいだろ
>ループ中にfunc()の戻り値が変化しないならA
そんな条件なら誰だってA案じゃなくて
D案(新案)
MyClass hoge;= func()
for (…) {
…
}
にするわ。
func()の戻り値が変化することはもう皆空気を読んで分かっていることだ。
あ、そりゃそうだな…なんかボケてるな俺
964 :
962 :2009/06/13(土) 08:23:54
pimpleで画像検索してみい
>>949 A 案 : 自主的にこう書く事はない。
B 案 : 基本的にこの方法にする。
C 案 : ループ後に hoge が必要な場合に限定。
A 案のコードは、状況に応じて B、C に直す事もある。
hoge の生成コストが予測不能だから A 案が安全、という主張もあるだろうが、
それは「早すぎる最適化」なので、コストが問題になるまでは、参照範囲を狭
める方向で実装したいな。
>>964 自分の間違いを素直に認められる奴が一番賢いんだ。
だからお前も自分の間違いを認めて俺と結婚しろ。
968 :
964 :2009/06/13(土) 15:32:30
>>967 それはまた新たな過ちを犯しているのでは?(笑)
969 :
963 :2009/06/13(土) 16:48:18
operator << って英語で何て言う? 標準出力演算子とか?
bitwise left shift operator
stream output operator double angle brackets
973 :
970 :2009/06/13(土) 20:57:55
グローバルなオブジェクトはパフォーマンスや初期化順序の問題等で出来る限り避ける べき、ということで自分のコードを修正しているのですが、 どの程度避けるべきか、避けるとしたら既存のコードをどう変更すべきか悩んでいます。 具体的な話だと、例えば文字列定数は、使っている文字列クラス(string等)の定数 オブジェクトで定義しておきたかったりします。 この場合にグローバルオブジェクトを避けるとしたら、どうしますかね? 例えば「定数文字列はCの文字リテラルで宣言しておいて、使うときに文字列オブジェクト を生成.」なんてのがありでしょうが、安直にやると毎回オブジェクトを生成することになり ますよね。かといって一旦生成したオブジェクトは破棄せず再利用、なんて考える と、コードが煩雑になるような... 似たようなことは文字列以外のオブジェクトでもありまして... いやはや。
static const std::string ConstantString = "I am hoge."; これじゃダメなん?
976 :
975 :2009/06/13(土) 21:05:42
static const std::string ConstantString("I am hoge."); でも同じ。
グローバルを避けろというのは、必要もないのに広く晒すことを戒めてるんであって 不変なデータとか、本当にプログラムの広い範囲から参照が必要なものをグローバルにするのは問題ない
初期化順序の問題は?
979 :
デフォルトの名無しさん :2009/06/13(土) 22:16:56
std::vector<double*>* から std::vector<const double*>* に変換するにはどうしたらいい? 全体をコピーする方法以外でたのむ。
>>979 std::vector<double*>*
と
std::vector<const double*>*
には継承関係とかが全然ないけど、全コピ以外でやる方法なんて存在しうるのだろうか?
reinterpret_cast< std::vector<const double*>* >
hoge->getval()->getval()->getval()->setupdate(); (getvalでメンバ変数として定義されたインスタンスのポインタを呼び出します) とかいうアホな実装を直すいい方法ないですか?
983 :
デフォルトの名無しさん :2009/06/13(土) 22:31:37
>>982 別にいいじゃん。
ツリーとかそうなるっしょ。
constオブジェクトを格納しても、結局イテレータで値書きかえられちゃうんだよね、VCの場合。
>>982 1回しか呼ばないならそのままで構わないと思う。
何度も呼び出すようなら
void Hoge::setupdate() { getval()->getval()->getval()->setupdate(); }
を定義して、
hoge->setupdate();
とするのは?
hoge->getval()->getval()->getval()->setupdate(); これって速度的にどうなんだろ?空の関数でも 呼び出し遅くないのかな?
インライン展開関数なら、インデックス引き1回。そうでないなら重い。 しかしそれ以前に、こんなことをしなければいけない設計に問題がある。
えっ なんで?
991 :
デフォルトの名無しさん :2009/06/14(日) 09:30:09
>>989 >なんで?
なんでって、俺ならそんなこと無くてもいい設計が普通に簡単に書けるから
>>992 どんなの?どんなの?
書いてみて?書いてみて?
書けこらぁ
お前システム設計したことあるのか? 無いだろう? 直接プログラム打ち込んでるだけじゃないのか?
>>992 そういうのは書いて叩き台作ってから話してね!ゆっくりしてないよ!
設計の話をたたき台にと言っているお子様には、笑いがこぼれます。
日曜おほほほ
そうだな、設定のたたき台を出しても良いが。 その前に、設計するための目的の仕様をキッチリ出してもらおうか。 その仕様書がしっかりしてて、暇があったら設計のたたき台を出そう。 今から出かけるから、それまでに出すんだぞ。
999 :
デフォルトの名無しさん :2009/06/14(日) 10:12:28
次スレ立てる
>>998 # 俺ならそんなこと無くてもいい設計が普通に簡単に書けるから
はあ?できないならできないって言えよ
ところでスレオワタ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。