388 :
361 :
04/09/14 09:53:58 >>379 設計の段階でヒープに確保するオブジェクトとスタックに積む
オブジェクトは「明確に区別している」ので、同じクラスの
インスタンスがヒープに確保されたりスタック積んだりとまちまちに
なることはないので、オーバーロードする必要はない。
クラスによってヒープに確保かスタックに積むかが決定している。
ヒープに確保するオブジェクトの例をあげればポリフォーリズムが
必要なクラス、スタックに積むクラスは通貨型やベクトル型、
複素数型、クォーターニオンなど。
C++ではオブジェクトをヒープで確保することを強制できないので
とりあえずコピーコンストラクタや代入演算子をprivate属性に
するぐらいはやっているが、最終的にはドキュメントに書いている。
Compositeパターンのように子ノードの削除の責任が親ノードにある
場合、delete演算子かスマートポインタで破棄するんですが、
これがスタックにつまれていると親ノードの都合で削除できない
ので問題になる。こういうのは仕様できっちりきめるしか
回避方法がないのはC++の欠点だと思っている。
...というか、こういうガイドラインって一般的ではないのかな。
とりあえずつかいわけとしてはC#の値型と参照型に近い
感じなんですが。
>>388 > 設計の段階でヒープに確保するオブジェクトとスタックに積む
> オブジェクトは「明確に区別している」ので、同じクラスの
クラスを使う側のローカルな操作なら自分の決定を前提とできるだろうけど、
クラスや関連関数を提供する側では、どちらに確保されるかと言う前提は持てないだろう。
> ヒープに確保するオブジェクトの例をあげればポリフォーリズムが
"polymorphism" な。
> C++ではオブジェクトをヒープで確保することを強制できないので
コンストラクタを protected にして、ヒープに確保するstaticな
生成関数を用意すればできるよ。
> これがスタックにつまれていると親ノードの都合で削除できない
> ので問題になる。こういうのは仕様できっちりきめるしか
> 回避方法がないのはC++の欠点だと思っている。
他の言語なら仕様でキッチリ決めないで回避できるの?
> ...というか、こういうガイドラインって一般的ではないのかな。
> とりあえずつかいわけとしてはC#の値型と参照型に近い
C#は詳しくないけど、それを表したいなら、
C#:値型 → C++:メンバを並べたクラス型
C#:参照型 → C++:実装へのスマートポインタひとつをメンバに持つクラス型
こんな感じの対応付けにならないか?
390 :
361 :04/09/14 10:40:07
>"polymorphism" な。 すんまそん。typoです。マジで恥ずかしい。 >コンストラクタを protected にして、ヒープに確保するstaticな >生成関数を用意すればできるよ。 そういえばそうだった。忘れていました。 C#だと構造体は必ずスタックにつまれる(ボキシングするとヒープに 移るけど)し、クラスはヒープに確保される。まあC#の場合はも ともとGCがあるからインスタンスの破棄のことは考えなくていいんだけど。
391 :
361 :04/09/14 11:13:37
>C#:参照型 → C++:実装へのスマートポインタひとつをメンバに持つクラス型 これって俗にいうHandle-Bodyだよね。これも設計ポリシーによってはアリですね。 昔の(今は知らん)xerces-cもそうだったような覚えがある。
横槍ですが...
>>388 >Compositeパターンのように子ノードの削除の責任が親ノードに
>ある場合
むしろ私の場合は、Compositeパターンによる関連性と寿命管理を
分離する設計が殆どです。Compositeパターンにより関連付けられた
オブジェクト群を利用するオブジェクトと同じ寿命を持った
オブジェクトを用意し、それに保持させるって感じです。
そういった意味では、ライブラリがクライアントの用意するオブジェクト
の寿命を管理する設計よりも、ライブラリはあくまでもそのオブジェクト間の
関連性だけを利用するようにし、その関連性の利用期間を外部に通知できる
ようなインターフェースを用意します。オブジェクトの寿命が本質的に
あいまいな場合のみshared_ptrを使いますが、稀なような気がします。
393 :
361 :04/09/14 14:48:48
>むしろ私の場合は、Compositeパターンによる関連性と寿命管理を >分離する設計が殆どです。Compositeパターンにより関連付けられた >オブジェクト群を利用するオブジェクトと同じ寿命を持った >オブジェクトを用意し、それに保持させるって感じです イメージとしてはFlyweightのようなオブジェクトプールを つかうって感じでしょうか?ちがったらすみません。 一応、GoFの本を確認したところ「component を削除するのは誰か」 という段落で「通常は親ノードが子ノードを削除するのが最もよい」 とは書いてありますが、そうでなければいけないとは書いてないですし、 例外のケースもあげられています。 >あいまいな場合のみshared_ptrを使いますが、稀なような気がします。 個人的にもshared_ptrをガーベージコレクションのかわりに つかうことは殆どないです。thisポインタ問題(shred_ptrの thisポインタはスマートポインタで管理されていない。 一応回避策はありますが)や循環参照でメモリリークが 発生したりするので意外とつかいにくいです。むしろ コンテナに入れることができる唯一のスマートポインタ というつかいかたが多いです。 クライアントが生成したインスタンスをライブラリ側で 寿命を管理する必要があるかどうかは議論の余地がありますね。
とりあえず、俺に責任は無い。
C++でポリモーフィズムを使う時って、ヒープに実態確保して、ポインタ使うしかないの?
スタックに確保して参照を使うのもアリです。
で、361よ。 > 個人的にヒープに確保したインスタンスの参照をとるのは > 抵抗があるかな。 これは具体的な根拠があるわけじゃない、ってこと?
398 :
361 :04/09/15 12:58:23
ヒープに確保したインスタンスを参照にすると削除するときに&演算子で ポインタに戻してやらないといけないのと、スマートポインタをつかう ことも多いので、参照をつかっているところとスマートポインタを つかっているところで表記がまちまちになって好きじゃない。 一貫性のある表記が好きという個人的な好みの問題。でも本当に わざわざヒープに確保したインスタンスを参照にする人って いるの? ポリモーフィズムは別にスタックに確保したオブジェクトでも できるけど、スタックに確保しちゃうとインスタンスの寿命の 管理の自由度が下がる。それにスタックに確保しちゃうと Factoryメソッドのようなメソッド内部で生成したインスタンス をメソッドの外部に提供するときにコピーコンストラクタが 必要になるのでそういうときに困る。例えばオブジェクトが ビットマップのような巨大なデータをもつ場合、コピーコン ストラクトのコストは大きいし、コピーコンストラクタを 書くのが難しいオブジェクトもある。なので必要のない コピーコンストラクタはprivateにして使用禁止にして つかわないようにしている。巨大なデータを持つオブジェクトは 前にもいった人がいるようにHandle-Bodyなんかでもいい (実際にHandle-Bodyをつかっていたり、文字列クラスなんかは CopyOnWriteをつかっている実装も多い)が、自分はHandle-Bodyを つかうスタイルではない。これもスタイルの問題。
400 :
デフォルトの名無しさん :04/09/15 14:16:46
ポリフォーリズムをポリホと略すスレはここです
| ポリフォーリズム の検索結果のうち 日本語のページ 約 7 件中 1 - 3 件目 (0.54 秒) あるからびっくりだ。
全部同一人物?
>>400 モーフィングとフォーミングを勘違いするなら分かるけど
フォーリングと勘違いするというのは飛んでるなと思う。
3カウント入れちゃうよ
だからマジtypoだって...。まだいりじるのか...。 本気で恥ずかしいんだからいじめんなよ。
>>いりじる いじるの間違いだ。またtypo。もう嫌...。
ていうか、ポリフォーリズムをモリモーフィズムと間違えるのって恥ずかしすぎ。
407 :
デフォルトの名無しさん :04/09/15 22:06:55
イリジウムのことね
はずかしすぎ。 アンテナでかすぎ。
どうtypoったらそうなるのか分からん
typoだけに突っ込んでいる人は、 そうやって話をはぐらかそうとしている 厨房なので無視するべし。
>>394 なんか、どちらかに誤解があるようだな。
>>364 の [依存]ケース2 で言っていることは、
たとえば「あるメソッド」foo について、
foo(T*);
というふうに引数の型として生ポインタを使うということじゃないの?
それに対して、
foo(T&);
のほうが適切ではないかと言う突っ込みを
>>374 で入れている。
これは引数の型の話で、確保したインスタンスを
保持するための型は関係ないと思うんだけど、
漏れが
>>364 を誤読しているの?
>>414 何度も同じようなことを書いてすまんけど、
1.クラス設計時にヒープかスタックか決めている
2.ヒープに確保するオブジェクトは常に(スマートポインタを含めた)
ポインタとしてつかいたい
3.参照をつかわないのは参照とポインタが混ざって表記の揺れに
なるからという好みの問題
別に参照をつかっちゃまずいっていう決定的な理由はない。
設計ポリシーとしてメソッドの引数は一貫して参照をつかうの
であればそれはそれでいいんじゃないでしょうか?っていうか俺が
文句いうことじゃないけど。
逆にちょっと質問。setterのようなあるインスタンスを引数の値とって
それをインスタンス変数に保持するメソッドで、かつ削除の権限が
そのsetterを持つインスタンスにある場合、これも参照で渡すの?
そうだとするとどこかの段階で参照からポインタに変換しないと
削除できないような気がするんですが。それともこの場合は
特別にポインタで渡すんでしょうか?
すまんレスの先が411だった。 質問の意図は指摘しているところで参照をつかうと、 setterうんぬんのケースと一貫性を保とうとすると 無理がある場所がでるんじゃないかってことです。
>>413 最初に突っ込みいれた箇所(
>>364 の[依存]ケース2)では
「渡されたインスタンスはそのメソッドの中でしかつかわれない」状況となっている。
「インスタンス変数に保持するメソッド」なら状況が違うんじゃないの?
これらの異なる二つの状況の間で一貫性なんてあるはずがない。
生ポインタ使う場所の例として挙げられた箇所に
参照のほうが適切だと突っ込みいれたのに、
スマートポインタ使う場所を挙げて反論されても困る。
> 削除の権限が そのsetterを持つインスタンスにある場合 どういう状況だかよく分からんが、std::auto_ptrみたいなものを 作ろうとしてるなら、素直にコピーを作成したオブジェクトが責任を持って オブジェクトを破壊すべきだ。 参照渡しされたものを受け取った側で破壊するのは、分かりづらい。 とりあえずスマートポインタ勉強してから出直せ。
漏れはリアルタイム画像処理をよくやるんだけど、 画像のピクセルデータにアクセスするときはなんとなく生ポインタ使っちゃうな。 あったり無かったりするものを引数にしたいとき、T* 型の引数にして 0 渡すと 「無し」みたいなこともたまにやるし。C# や Java のライブラリでも null 渡せる メソッドは結構あるから、実装面ではポインタ型の使いどころはそこそこあるん じゃねーの?
まあ、あれだ 参照渡しでもポインタ渡しでもコピー渡しでもなんでもいいけど、 参照剥しをするのは控えた方がいいな。 あとでdeleteするオブジェクトはポインタで保持しとけ。
419 :
ポリホ :04/09/17 17:46:25
>参照渡しされたものを受け取った側で破壊するのは、分かりづらい。 からポインタつかえっていってんだろ。 >「渡されたインスタンスはそのメソッドの中でしかつかわれない」状況となっている。 >「インスタンス変数に保持するメソッド」なら状況が違うんじゃないの? >これらの異なる二つの状況の間で一貫性なんてあるはずがない。 状況が違うから一貫性がなくてもよいという判断なら別にいい。 自分はポインタにすると2つの状況で整合がとれるから好きなだけだ。 メソッドの引数はポインタうんぬんという話はヒープに確保した インスタンスに限定の話だ。しかもコーディングスタイルの問題 だから人のことはとやかくいうつもりはない。 ヒープに確保したインスタンスの参照剥がしが好きじゃないといったら 根拠を求められるし、好きじゃない理由をいったらなぜか参照剥がしは わかりずらいっていう謎のつっこみが入るし、わけがわかりません。 いったい自分にどうしてもらいたいんだろう。
>>411 foo を書いていて引数にnull 値のようなものを許したいとき、
foo(T*) にするか、foo(T&) にして T::Null を提供するかっていうと、
漏れはメンドクサイから大抵前者だけど。
>ポリホ もうちっと日本語勉強しろよ
>>419 >いったい自分にどうしてもらいたいんだろう。
いじられ役に徹してくだちい。
とりあえずC++ではヒープではなく「フリーストア」って呼ぶんじゃなかったっけ? まぁ、データメンバを「メンバ変数って呼んじゃダメなの?」くらいの勢いだけど。
int* a,b; と int* a; int* b; って違うんだな・・・
>>424 いや、それは違いすぎだから…。
両方ポインタにするなら
int* a, *b;
じゃないとね。
だけどこういう書き方になるから型の後にアスタを付けるスタイルは好きではない。
int *a, *b;
のほうが美しいじゃん。好みの問題かもしれないけど。
>>424 所詮C++はC言語のころの呪縛から逃れられてないのよ。
>>425 int* a;
int* b;
と2行に分けることを推奨。
>>426 >所詮C++はC言語のころの呪縛から逃れられてないのよ。
だがそれが(・∀・)イイ!!
というか、仕様変更するとコンパイルエラーが発生するレガシーコードが
混在してしまう可能性があるから仕方ないっしょ。
・・・レガシーという単語を使いたかっただけだ。気にしないでくれ。orz
428 :
デフォルトの名無しさん :04/09/24 08:39:01
int* をtypedefして違う名前を与える さらにはintを変えられるようにtemplate化
C言語の型とは何か。 typedef int *iptr; int *は ptr->int iptrも ptr->int int *[]はarray->ptr->int int (*)();はptr->function as int int *();はfunction as ptr->int struct { int a,b;} *;はptr->struct{int a;int b;} 構造が同じなら互換性があると言う。 iptr a; int *b; a = b; // ok しかし struct { int x,y;} a; struct { int x,y;} b; b = a; // error '=' : 互換性のない型が含まれています。 これはいったい、どうしたことか。
>>429 b=a;
が
b.x=a.x;
b.y=a.y;
と同義であるとはいえない。
直感的にはそうであるが。
同義であるなら同義であるとoperator=なりで
コンパイラに教えなきゃわからん。
>>429 struct A { int x,y;} a;
struct B { int x,y;} b;
名前を省略しただけの扱いなんだろ。
別々の構造体で、たまたまメンバの並びが同じになっただけで代入ができたら困る。
C++スレでC虫臭い話を続けるな
>>424-425 こんな解決法もある。
typedef int *PINT;
PINT a, b;
それ終わってる。 とっくに。
>>429 基本的に別の型に代入はできない。当たり前だけど。Java だって C# だってそうでしょ。
typedef は単なる別名で、新しい型を作る訳では無いって、仕様で決まってますから。
メンバの並びが同じな別々の構造体を作る必要性はあるのか?
あたりまえ
>>436 「今はたまたま同じメンバだけど、将来的には拡張されるかも知れない」
ってことはありそう泣きガス
>>438 その場合、直接代入できる必然性はないよね。
ふと思ったんだけど、構造体やクラスの(データ)メンバを while文のようなループ文でくるくる回しながら順番に取れたら便利かも? 名前とか個数とかデータ型を意識せずにクルクル…。 そういうのってうまいこと出来ないかな?
>>441 型の違うデータメンバのいったい何が取得したいのか? ってことだね。
たとえば各メンバの文字列表現が取得したいのなら
そのような関数を用意すればすむ。
うっ、わかりにくかったか…。orz 例えば擬似的なコードを書いてしまうと…。 struct TEST_STRUCT { int mInt; long mLong; char mChar[255 + 1]; }; void main() { vector<VARIANTのような型> dstArray; ^^^^^^^^^^^^^^^^^^^^^ TEST_STRUCT srcData; //適当に初期化済みの状態とする int i = 0; while( 1 ) { dstArray.push_back( srcData.○[ i ] ); i++; ^^^^^^ } } こんな感じで、データメンバを「名前ではない方法」でアクセスできれば、 結構便利な使い方ができそうだなぁと思ったのでつ。 「○[ i ]」の部分って必ずデータメンバの名前で指定しなければならないから…。 dstArray.push_back( srcData.mInt ); dstArray.push_back( srcData.mLong ); …のように一つ一つ全部指定しなきゃいけないし、型に「VARIANTのような型」が無い以上、 そういうやり方すら出来ないではないでつか…。 関数にしても結局はすべて名前で指定しなければならないし…。
>>444 しまった、ループの脱出条件を書いてないから無限ループケテ〜イだ…。orz
まぁ、その辺は突っ込み入れないでちょ。
>>444 offsetof
使った事無いけど。多分。
>>444 つーか
TEST_STRUCT srcData[] = ...;
for( int i = 0; i < ...; i++ )
dstArray.push_back( srcData[i] );
じゃなくて?
>>444 実体でなくポインタを維持すればいいなら、
std::vector<void *>dstArray;
dstArray.push_back(reinterpret_cast<void *>(&srcData.mInt));
dstArray.push_back(reinterpret_cast<void *>(&srcData.mLong));
dstArray.push_back(reinterpret_cast<void *>(srcData.mChr));
構造体のメンバの列挙は誰かがやらないといけないからねぇ。
static const unsigned sOffsets[] = {
offsetof(TEST_STRUCT, mInt),
offsetof(TEST_STRUCT, mLong),
offsetof(TEST_STRUCT, mChr),
};
for (unsigned i = 0; i < sizeof(sOffsets) / sizeof(*sOffsets); ++i) {
dstArray.push_back(reinterpret_cast<void *>(reinterpret_cast<char *>(&srcData) + sOffsets[i]));
}
これでもなんとかなるかな。
>>446 「offsetof」なんて初めて聞いた!
…と思ったらひょっとしてC++の言語仕様にはないものですよね?
ぐぐってみたらどうやら「.NET Framework」なのかな?
>>448 ふむふむ、ポインタを駆使すれば結構なことが出来そうですね。
しかしなんていうか難しいというかちょっぴり複雑に…。(^^;
基本的に私もメンバを一つ一つ指定することになんの抵抗も無かったんですが、
最近職場でBorlandC++Builderに慣れた同僚が、
「構造体のメンバって一つ一つ名前でアクセスしないといけないんですかねぇ?
面倒くさいですねぇ」
…などと話していたので、興味を持った次第でつ。
これができるとどういうメリットがあるかという話ですが、
(C++Builderの話限定になってしまうのですが)
DBの不特定なテーブルから、フィールド名を指定せずに
不特定の構造体のメンバにデータを突っ込めるため、
プログラムの汎用性が高まるということらしいです。
offsetofを知らないだけならともかく(それも問題だが)、C#って・・・ 絞り込みも出来ない、googleのトップしか見ないで、2番目は無視する人かね
>>449 offsetofなんて、Cでもマクロで簡単に書ける代物なんだけど。
標準ヘッダを探してみることもできないのかな?
うわ〜ん、そんなにいじめるなぁ〜。ヽ(`Д´)ノ 簡単にできるというのがいいのだよ。 めんどっちいのはイヤ。
しかし、とりあえずoffsetofというマクロが 標準的に用意されてることを教えていただき、 ありがとうございますた。m(_ _ )m
クラスのメンバを、別々に、同じベクタに入れる意味がわからん
455 :
デフォルトの名無しさん :04/11/25 02:44:24
最近書き込みがないね。
重複スレだからな。
C言語とJavaとRuby使って,そこそこ書きました. 次はC++にチャレンジするかと,プログラミング言語C++を買ってきました. 難しいです.何書いてるのかわかりません. 俺の頭が悪いのが原因でしょうが,C++の難しさに挫けそうです
ヽ(冫、)ノズコーッ 何処が難しいか言ってみて。 十分習得出来る知識あるように見えるけど…
>>458 >十分習得出来る知識あるように見えるけど…
んな事が
>>457 読んで解るのか!ESPer でつか?
>>457 CからC++に移ったばかりの人
for (int i = 0; i < 10; i++) {
v[i] = 1;
}
C++を使い慣れてきた人
for (std::vector<int>::iterator it = v.begin(); it != v.end(); it++) {
*it = 1;
}
C++が「使える」と言えるレベルの人
std::fill(v.begin(), v.end(), 1);
これでやっと中級に入門です。先は長いです。くじけそうです。
C++のことがある程度わかってくると、++、--は前置にするもんです。
運置
464 :
デフォルトの名無しさん :04/11/26 21:17:08
>>464 前置の方がコピーのコストがかからないから
>>466 More Effective C++の項目6を嫁
>>467 読んでみた。ありがとう。
インライン展開されるような場合は別に気にしなくていいね。
>>461 それ見てC++の方がタイプ量多い割にたいしたこと出来ない。
Cの方が1000万倍マシと悟った。
>>469 それはちょっと勘違いだ。
C++ は C より便利だよ。
>>467 んじゃ、これから
Effective ++C
と書くことにしちくりマンボ
>>468 テンプレートでの汎用プログラミングのために常に
前置にしておくと後々組み込み型をクラスにしたくなった
とき修正量が減る。
>>473 組み込み型かクラスかは別に関係ないような?
>>474 クラスだとテンポラリオブジェクトが生成されるよ。
インライン展開されてもね。
思ったよりレスが…ありがとうございます.
>>458 最初は俺も楽勝だろーとか思っていたのですが,何故か頭が受け付けません.
>>461 今の俺の書き方だと,モロ最初の書き方ですね…
>>461 の二番目みたいに、全く抽象化されてもいないのに
無理やりイテレータ使う意義って、全くないように思えるんだが
インポラリ
>>457 > C++の難しさに挫けそうです
「プログラミング言語C++」の難しさに挫けそうなだけだろ。
>>479 そんなことはない。
少なくともコンテナを差し替えられる。
そんなこといったら、最初の書き方ならば vectorを配列にさしかえれるという利点があるなw
>>483 vectorを配列に差し替えても、あまり嬉しくはないだろう。
速くなるやん
>>485 そういう用途なら、boost::arrayがあるから利点とはならない。
boost::rangeでcontainerとbuilt-in arrayが汎用に扱えるようにもなったしね
後からコンテナを差し替えやすいってのが利点。
コンテナの差し替えなんかするのか?ホントか? テンプレート引数で型を受け取るときに、 どのコンテナでもOKなのは、確かに意義があるといえるが 前述の例はそういうわけでは全くないし、 正直、三つある例のどの書き方でも、優劣はないと思うが
前述の例だけみればたしかにどれでもいいレベルの話だけど、 意識の持ち方のことを言ってるんじゃないの? できるだけSTLコンテナやSTLアルゴリズムを使おうという。
しっかし、組み込み型(intとかdoubleとか)のコンテナならSTLのアルゴリズムは 教科書通りに使えるんだが、クラスになると途端に使い物にならなくなるのは どういうこと? STLの範囲で済ます場合、メンバ関数ならアダプタでなんとかなるが、メンバ変数は 叙述関数・関数オブジェクトを用意しなければならない。 正直、boost::bindやboost::lambdaが無かったらやってられないよ。 でもこれも一長一短で、boost::lambdaは動かないコンパイラもあるし(bcc32)、 boost::bindは遅いし。
> boost::bindは遅いし。 なんで?
>>492 なんでだろう? 俺が聞きたいよ。
アセンブリコード見たけどよく分からん。あまり最適化されてない様子。
lambdaは早いんだけどな。
単純なlambda式なら、イテレータをループで回すより早かったりする。
495 :
デフォルトの名無しさん :04/11/28 23:49:47
boostの一部のライブラリを見てると、素直にC++にクロージャを足した 新しい言語を作って使えよと言いたくなる。
boost使ってる時点で負け組み
>>496 何を使うと勝ち組みになれるの?
boost のめざそうとしているものを使わなくてもいいってこと?
499 :
デフォルトの名無しさん :04/11/29 08:41:38
C++が難しいのは、テンプレートのがポリモルフィズムより速いからだと思う。
500 :
デフォルトの名無しさん :04/11/29 08:55:56
501 :
デフォルトの名無しさん :04/11/29 09:53:18
>>495 templateの良し悪しはともかくとして、
言語のコアとしてそういった概念のシンタックスを
持つのではなく、メタプログラミングによって後から
追加できるのっていいなと思うけど。
502 :
デフォルトの名無しさん :04/11/29 11:15:07
このスレ見てるとげんなりしてくるなw
>>501 同感、クロージャーなどを突っ込むよりtemplate機能をもっと整理して
この種の機能はライブラリとして実装してもらいたい。
クロージャー以外にもデザパタ一式ガベコレ一式程度は自働ジェネレートできるくらいがいい。
言語のコアはあくまでシンプルで高速な物がいい。
504 :
デフォルトの名無しさん :04/11/29 12:55:33
VC++で計算した数値を引数で表示したいんですが、printfで表示されません。だからMessageBoxを使って表示したいんですがエラーがでます。どうしたらいいんでしょうか?どなたか分かる人教えてください。
( ゚Д゚)ポカーン
506 :
デフォルトの名無しさん :04/11/29 15:55:09
505うぜーよ!! 知らないならくるな!!! 消えちまえーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
質問した本人はそのスレ全てを覚えてるとは思えないが…(笑)
C++はSTLと継承を使いこなし始めた辺りが 生産性・理解向上の分水嶺だった記憶がある。
>504 ConsoleとWinアプリは違うから。 デバイスコンテキストをキーワードに勉強しる。 あとこの手の質問はVC++のスレ・・・って適当なの無いな今は MFC限定しか
>>511 ★初心者にVisual C++を教えるスレ★ Part16
C++には、他に類を見ない自由と絶対的な○○が与えられている。
C++の機能限定版とか無いの?
>>514 例外、クラス、関数オーバーロードや
デフォルト引数などの機能を取り除いた
C というものがあります。
>>516 例外処理が省かれてるのが最大の問題だな。
>>518 テンプレートも名前空間もない。
実際にEC++環境があったのでコーディングしてみたことがあるけど、
全然C++らしくない。
まああくまでもembeddedだからねえ。
時々、ECMAScript をバイナリに落とすことが出来ればと考えることがある。 obj = new Object; obj["Method"] = function( a, b ) { echo("OK"); } obj.Method(); // OK 441 がやりたいことも、プロトタイプ取得で簡単OK
漏れの考えはこうだ! >461 様の例で「CからC++に移ったばかりの人」の書き方は いかにも効率が悪そうな印象を受けるけど、 漏れが「仕事で」プログラムを作るなら、 迷わずこのやり方を取る。 (かなり馬鹿にされるだろうけど…。) そして趣味で(個人的な事情で)プログラムを作るなら、 「C++を使い慣れてきた人」や「C++が『使える』というレベルの人」のような 書き方ができるように努力するだろう。 なぜなら仕事でプログラムを作り、それを他の技術者に引き継ぐ場合、 単純な書き方がもっとも無駄な手間を省くからだ。 そして多くの場合、理解しにくいバグの発生を予め抑制することができる。 また、改修を加えるときや、 不幸にしてプラットフォームの異なる環境へ移植する場合にも、 少ないコストで作業を終えることができるであろう。 スレ違いで申し訳ないけど、 引継ぎ作業によるコストって、 プログラムの書き方で随分変わるんですよ。 「凄いC++技術者」の書いたプログラムを引き継いだ場合、 「凄くないC++技術者の私」が改修を加えるのは大変なんですよ。
>>522 ごく普通なC++プログラマな私からすれば、他人のソースを引き継いだときに
ループが書いてあったらそれだけで要注意項目になります。
std::fillならそのまま読み飛ばせる分だけ、引き継ぎコストは抑えられるわけですな。
構造体も然り。初期化処理をその構造体を利用する側でやらなければいけないよりは
コンストラクタを書いておいてくれたほうがよっぽど確実。
まぁ、「凄くないC++技術者=C++をベターCとしてしか使えない技術者」というなら別ですが。
ようするに522が凄いC++技術者になればいいだけ。
525 :
デフォルトの名無しさん :05/03/12 16:40:27
なんで一時オブジェクトは非const参照に変換できないんだ template<typename E, typename T, typename A, typename Value> inline std::basic_string<E, T, A>& ToString(std::basic_string<E, T, A>& rstr, Value t) { return rstr = static_cast<std::basic_ostringstream<E, T, A>&>(std::basic_ostringstream<E, T, A>() << t).str(); } //static_castしないとエラーを吐く。これはコンパイラのせいだと思う。 #define ToStr0(t) ToString(std::string(), t) template<typename E, typename T, typename A, typename Value> inline std::basic_string<E, T, A>& ToString(std::basic_string<E, T, A>* pstr, Value t) { return *pstr = static_cast<std::basic_ostringstream<E, T, A>&>(std::basic_ostringstream<E, T, A>() << t).str(); } #define ToStr1(t) ToString(&std::string(), t) int main() { cout << ToStr0(5) << endl; //エラー:一致するものが見つからない cout << ToStr1(.125) << endl; //OK return 0; } って書こうと思ったんだよ。 そしたらふと思いついてこうしたら動くんだよ。 #define ToStr0(t) ToString((std::string&)std::string(), t) 頼むからこんなのキャスト無しでも適当にやってくれよ。 そもそもオブジェクトを値渡しで返そうとするとインライン展開できない ってのがなけりゃこんなことで悩む必要は無かったんだよ>Borland
それはインライン展開しない方がいいと思うが。 つうか、boost::lexcal_castとか素直に使った方がええんじゃないの?
>>526 lexcal_cast.hppをインクルードするとエラーになってしまうもんで。
>>525 > //static_castしないとエラーを吐く。これはコンパイラのせいだと思う。
ostream に対する operator << の戻り値は ostream& だから、
コンパイラに依らずエラーになるはず。
一時オブジェクトで処理しようとしているのが間違い。
>>523 for ( xxx i = foo.begin(); i != foo.end(); ++i.) {
nannka(*i, arg1, arg2, arg3);
kannka(*i, arg4, arg5);
}
こんなのは、NGで
一回しか使わんつまんねえファンクタわざわざ宣言して
for_eachなりつかわんとNGなんだよな?
アンタがそうゆう主義なのはかまわんが
それがごく普通かねえ?
つうか、実務経験なさそうなふいんき
>525 形式的には、一時オブジェクトは右辺値なので非 const 参照に変換できない。 非 const 参照→呼び出された側で変更される + 一時オブジェクト→もともと定数だった可能性がある / すぐに破棄される =定数のものを変更しようとしている / 変更された値が破棄される ということでデフォルト安全側に倒してるんじゃないでしょうか。
>>529 んにゃ、一々ファンクタ書くまでもない処理ならループでもいいんでない?
ただ、ファンクタもいらんような単純な処理まで一々ループを書くなって話。
適切な比較オペレータを持っているクラスだというのに一々findループを書く神経は疑うってことね。
まぁ、>529の例ならファンクタ書かれるよりはループで書かれた方がよっぽどまし。
更に言えば、for (int i = 0; i < foo.size(); i++) なんて書かれるよりずっとまし。
そこでlambdaですよワラ
>>531 しょーもないことにこだわってるあたり覚えたての学生とみた(遠い目
「まし」とか繰り返して、さも自分にはもっといい案があるかのように匂わせておいて 結局そのまま書かずに退散するのが「らしい」ですよね ;-)
んー、ないよ〜 単にどっちがいいかって書いただけだし。 ファンクタを作らなくてもalgorithmのfind使えるケースで自分でループ書くのや iterator使わずに制御変数でループを回すのが要注意だって話で。 >529の例ならそれでなんも問題ないんでない? #そもそも私自身がファンクタ作るの苦手だw
C++よりMLの方がいいよ。
まあバランスが大事だよな
538 :
デフォルトの名無しさん :2005/03/25(金) 07:52:46
C++はすさまじく肥大化した言語。しかし、慣れると機能が多くて便利なのも事実だったりする。 シンプルといわれていたJAVAもバージョンが新しくなるにつれて肥大化が進んでいる。 C#はC++から機能を削ったとはいえ、機能を付け加えているから最初から肥大化している。 機能が多い言語は必ず肥大化し、複雑になってしまう。 シンプルで初心者に優しいけど「不便な言語」よりは、複雑で便利な言語のほうが良いと思が、 複雑な言語は初心者には優しくない。 初心者にやさしい「複雑な言語」があれば望ましいけど、それは無理かもしれない。
>>538 (行き着く先は)自然言語。
そして曖昧さと冗長性が増える罠。
シーピーピー シーピーピー シーピーピー シーピーピー シーピーピー シーピーピー シーピーピー シーピーピー ろ く な も ん じ ゃ ね ー
負け犬?
542 :
デフォルトの名無しさん :2005/04/26(火) 23:11:19
int n; n.~int(); これがコンパイルを通ってしまうのに驚いた。 こんな関数にint型の値を渡してもコンパイルが通ったからまさかと思ってやってみたら通った。 template <class T> void Destroy(T& t) { t.~T(); }
>>542 VS.net2003だと下のテンプレ関数のみ通った。
n.~int();は error C2059: 構文エラー : ''<L_TYPE_ambig>'' って出る。
テンプレートじゃなくても通るのが正しいような気がする。
>>538 今ならまだD言語のライブラリは少ない…貧弱
C++もなにかしようと思ったら機能が貧弱だよ GCもないし、拡張工事をせざるを得ない 良くも悪くもCなんだな
>>546 そうだね、あせんぶらにもGCつければべんりだね(わら
>>546 そうじゃなくて、君の頭じゃC++は無理なんだよ。
何見当違いの煽りをしてるんだか。
javaは.closeを書かせておいてGCがあると 主張するのは無理がある。同期のコードなんてCそのものだ。 そういえばGenericsもプリプロセッサで実装しているし assertの実装は失笑である。javaは新しいCなのだろう。 DはRAIIというのがあるようだ
C++はむずかしいので、機械語で書いてます。
>551 俺にはそっちの方がムズい…
BCBのヘルプに 「alloca 関数の使用はあまりお勧めできません。」 って書いて有るんですけど、そうなんですか?
>>553 スタックを食い潰すし、移植性に乏しいからでは?
C99ならVariable Length Arraysを使ったほうが良いかと。
C++ならstd::auto_ptrを使ったほうが良いかと。
仮想関数を使えばswitch-caseの嵐から抜けられるわけで、個人的にはそれだけで大満足です。
>557 だね。場合分けをすることなしに、異なる振る舞いを事前に記述して、コンパイラ任せにできる 有利性、というか。 でも、その有利性を理解できない層というのも確実にあって、それは何かっつーと、 仮想関数という概念、というか言語仕様を知らない層なんだよね。C++はもちろん、 Javaも知らないという層。switch-caseで、あり得る場合分けが全部ソース上に 明記してあった方が判りやすいしデバッグしやすいじゃん、と主張してきそうな、 えてしてそういう層が実装仕様を決めやがるんだよなあ。おっとこれはグチだな。すまん。 誰か強力に布教してくんねーかな。俺はもー疲れた。
>>558 無理。そういう層は大抵「学習意欲」<「日々の仕事をこなすこと」だから。
switch-case の代わりとしての仮想関数なら C でも出来るわけで。
C++儲のおいらでも560には半分同意。 switchの代わりなら構造体+関数ポインタでも それほど労力がふえるとも思えない。 勿論、仮想関数の方が楽なのは事実だけど。 むしろ、Cで困るのはコンストラク・デストラクタ・templateがない事。 auto_ptrを見ても分かるようにデストラクタが非仮想であっても、 templateと組み合わせればものすごく便利になる。 これが無い故に生成と破棄がセットになったリソースを複数作る 処理で、生成失敗時の破棄処理を書いてるとうんざりする。
要するに、リソースリークを避けるための下らない労力、プログラムの本質 から大きく外れたロジックやコードがCでは多くを占めてしまうってこったよな。 文字列やリストなんて単純なものも、Cでは悩みの種だ。 まあメモリリーク回避だけならGC使う手もあるがなー。 GC使えるような環境なら今時Cなんて使うなよという話もあるが。
この速度ならぬるぽ
>564 ガッ! ちゅーかまたお前かっ!
sageてぬるぽもなかろうに それよか、こんな過疎スレで sageぬるぽに3分でガッした565の方が神
567 :
デフォルトの名無しさん :2005/07/24(日) 23:15:44
int main() { std::locale::global(std::locale("japanese")); _bstr_t bs(L"ほげ"); std::wcout << bs << std::endl; //static_cast<const wchar_t *>(bs)とすれば無問題。 return 0; } VC7.1だとbsはconst wchar_t *か悪くてwchar_t *へ変換されるかと思いきゃ、 なぜかこれに解決される。せめてconst wchar_t *とであいまいにしてくれよ。 template<class _Elem, class _Traits> inline basic_ostream<_Elem, _Traits>& __cdecl operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const char *_Val)
568 :
デフォルトの名無しさん :2005/07/30(土) 10:43:10
今更だけどブロック内での関数宣言を廃止し、全て変数宣言と見なすという仕様にすれば良かったのにと思う。
>>569 コンストラクタ呼び出しで作った一時オブジェクトでローカル変数を直接初期化できる。
struct S0 { S0(); };
struct S1 { S1(S0 zero); };
int main()
{
S1 x(S0()); // 現行の規格では関数宣言
...
}
>570 S1 x = S0(); で回避できると思うけど、いちいち気にするのがいやってこと?
>>571 その書き方だと暗黙の変換とコピーコンストラクタが必要になる。
S1を↓のようにするとコンパイルできない。
struct S1 { explicit S1(S0 zero); };
struct S1 { S1(S0 zero); private: S1(S1 const&); };
>>569 ブロック内で関数宣言する奴なんて見かけない。みんなヘッダをインクルードする。
570みたいなコードは誰もが最初変数宣言だと思ってはまる。
それだったら全部変数宣言にするほうが、わかりやすいんじゃないかと考えた。
たとえば「ブロック内では関数宣言をしたければexternを付ける必要がある。
externなしで関数・変数宣言どちらともとれるときは変数宣言」とでもすればよかったのにと思う。
>>573 Cとの互換性を最優先した結果、なんだろうなあ。
>>570 S1 x((S0()));
()の2バイト分も面倒か?
対処法の有無はこの話題には関係無いだろう。
>576 その対処法によって、570のいう、 > コンストラクタ呼び出しで作った一時オブジェクトでローカル変数を直接初期化できる。 ことができない(実際にはできる)という、現行規格への不満が解消されるのだから関係ある。 まぁ570が、一時オブジェクトをローカル変数のコンストラクタに渡す文法を知らなかっただけのようだが。
578 :
570 :2005/08/02(火) 01:51:48
知ってたよ。
一見変数宣言に見えてしまうややこしさを問題としてるという論点に気付かない
>>577 を暖かく見守る俺が579ゲットですよ
580 :
577 :2005/08/02(火) 10:28:59
結局568の主張は、 とくに機能的な違いはないけど、今の文法は見た目がわかりにくいから、 ブロック内での関数宣言を廃止し、全て変数宣言と見なすという仕様にすれば良かったのに ってことなのね。 ぱっと見のわかりやすさは重要だと思うけど、もう二重に括弧つける癖がついたんで、どうでもいいかなと思う。 >579 サンキュー。これからも暖かく見守ってください。
このスレの人たちは英文をバリバリに読めるのか? 俺全然読めない。
英語しかなければ読むけど、ちょっと下手という程度なら日本語に喜んで飛びつきますが何か。 規格だってISOではなくJISの訳を読むし。
キチガイ翻訳はお断りだが
それが出来りゃ原書読むわい
糞 ス レ 勃 て て ん じ ゃ ね え よ 脳 挫 傷 !
プギャ(ry
589 :
デフォルトの名無しさん :2005/09/03(土) 20:06:30
OSのベータ版を市販するやり方は どこにもマネできないくらい最強
ポインタと参照を混ぜるとややこしいから、ポインタで統一してるんだけど 参照しか使えない場合もあるしなんなんだよ!!
俺はなるべく参照を使って、仕方ない時だけポインタを使う
593 :
591 :2005/11/29(火) 14:48:00
あっそうかスマートポインタ使えばいいんだって使ってるプロジェクト 見たことねえorz
594 :
デフォルトの名無しさん :2006/01/04(水) 11:55:46
もっともっと難しくなって構わないから早く来いC++0x。 なんてこのスレで言うとぼこぼこにされそうだ。
C#に慣れてきたらC++触るのテラダルくなってきた… つーか、同じVisualStudioなのにエディタの出来があからさまにVC#>>>>>>VCなのは何の嫌がらせだよ
597 :
デフォルトの名無しさん :2006/01/08(日) 01:29:03
>>595 C#はM$が作った言語だからJava、Delphi潰しをしながら
普及のために本気にならんといかんのだよ
C++についてはM$の都合におかまいなく拡張されたりするから
ほんとはサポートすんのヤなの
だけどC#がコケた時の保険のつもりで一応サポートしとくの
これが戦略。わかる?
ほんとはC#、VBで世界を支配したいの
あとはオマケ
>>597 2バイト文字使うなら
せめて♯を使えよと。
エディタはEmacs系を使えばいいのだ、勝手に補間するVSの親切エディタとは手を切れ、 あれは人を堕落させる。
>>595 言語仕様が複雑でC#よりマンドクセからじゃないかなあ。
>>595 なんか、MSはC#を無理やり推し進めている感じだしね。
FXではWIN32 API呼ぶのにオーバーヘッドがあるようだし・・・
つーかアプリのパフォーマンスにAPIのオーバーヘッドなんざ ほとんど関係ないと思うが。処理の9割以上は自分のコード の中だろ?
だから、30歳過ぎて、社会の政治的な要因に太刀打ちできるような 立場になってからもデザインパターンみたいな一技術で重宝されるような 人物に対して「逃げ道だよな」って言ってるの。20代の奴がやりたくてもできないような ところで自分をアピールする術を持ってないのかって。 中堅者のやることっていったら、20代の奴が仕事をしやすいように、いろいろと根回しすることだろ? 年齢重ねても、やることが20代の延長だったら会社に居る意味ねーよ。 スパゲティコードだとか、その辺は中堅社員が口出すことじゃねーって。 むしろ、20代の奴が気付いて、中堅社員に意見をUPして、それから中堅社員が根回しするのが理想。 要は、いい歳こいて低レベルな話してんじゃねーよって。もっと抽象的になれってことだ。
日頃誰にも吐き出せず溜め込んでいたモノを一気に吐き出したようだが、 そうやって長年熟成させてきた割には深みゼロなのが哀しいね。 まぁ、この程度の頭だから、誰にも認められずストレス溜めてるんだな。
607 :
デフォルトの名無しさん :2006/01/14(土) 13:09:20
>>606 では君が深みのある話をしてくれ。ぜひ読みたい
普通に603より609のほうが深いのが悲惨だなw
繋がりがまるでない。
>>614 批判に対して「じゃあお前がやってみろ」というのは
反論にも何にもなってないわけですが、
小学生くらいだと別におかしいとは思わないようですね。
お前らもっと生産的なことに労力を使うように汁。
C++を使いはじめて10年以上になるが、 これまでC++をC++として使える奴って未だ見た事がない。 このスレでC++を絶賛している奴は本当にC++を使いこなしているのか疑問。
2chだし、ピンキリいると思うよ。
そもそも何を持ってC++をC++として使っているというのかが曖昧。
>>618 おまいの周囲の連中のレベルなんか知ったこっちゃないが
>このスレでC++を絶賛している奴は
「絶賛」する奴 (いたっけ?) は信用するな。
見た目だけで「あいついい女だよな」っつってる奴は
その女と付き合ってるわけではない。
そもそもオブジェクト指向が難しすぎ gotoを使って何が悪いんだ
>623 オブジェクト指向とgoto不要論を同じレベルで論じるなよ
626 :
デフォルトの名無しさん :2006/05/22(月) 14:29:18
>>595 >つーか、同じVisualStudioなのにエディタの出来があからさまにVC#>>>>>>VCなのは何の嫌がらせだよ
だよな
627 :
デフォルトの名無しさん :2006/05/24(水) 11:55:09
C++の標準化委員会は冒険的に過ぎるところがある。 C++がこれだけ強力な言語になったのは彼らの力だけど、 いろいろと取り返しの付かない失敗をしている。 slice_arrayで大恥をかき、exportや<cNNN>ヘッダで実装者を悩ませ、 言語仕様の穴を利用してauto_ptrを実装してしまう。 koenig lookupなんかは、ライブラリの設計ミスを言語仕様側で 取り繕おうとして傷口を広げた例だね。 もう少しやる気の無い連中、あるいは後方互換性にこだわらない連中が 標準化をやっていればこんなに難しい言語にはならなかっただろうに。
で、C++のどこが難しいんだ? クラスが分からないのか?
>>627 概ね頷けるところだが、
> koenig lookupなんかは、ライブラリの設計ミスを言語仕様側で
> 取り繕おうとして傷口を広げた例だね。
これだけ、聞いた事が無い話だった。
何のこと?
後方互換性は、言語使用の複雑さの原因であることは確かなんだが 普及の速度には大きく貢献してるだろうから、単純に否定できないと思うんだ。
まぁ、実際に携わってみれば誰もが苦しむところだろうな。
>>631 まあそうなんだけど、予約語の使いまわしが
初学者を混乱させてんじゃないかな、と。
634 :
デフォルトの名無しさん :2006/05/24(水) 18:51:51
ケーニヒがなかったら a + 1 // OK a.operator+(1) 1 + a // NG my_namespace::operator+(1,a) // OKだが書いてられるか
D&Eを読めば嫌と言うほど互換性確保に努めてきた様子がひしひしと伝わってくる。
初学者のためにOSのカーネルがコンパイルできなくなるなんて 許されないからな
637 :
デフォルトの名無しさん :2006/05/24(水) 23:01:13
>>629 >>634 operatorやswapをこんな感じにしておけばKoenig lookupは要らなかった。
lessを提供すればless_equalも勝手に実装してくれるとか、
そういう仕組みを作ることもできる。
namespace std {
...
namespace hooks {
template <class T1, class T2>
struct plus_traits;
template <class T>
struct plus_traits<std::complex<T>, std::complex<T> > {
typedef std::complex<T> result_type;
static std::complex<T>
plus(const std::complex<T> &a1, const std::complex<T> &a2)
{ ... }
}
}
}
template <class T1, class T2>
std::hooks::plus_traits<T1, T2>::result_type
operator+(const T1 &a1, const T2 &a2)
{ return std::hooks::plus_traits<T1, T2>::plus(a1, a2); }
>>637 それだと operator+ を定義していないクラスに + を使おうとしたとき、
plus_trais についてのエラーメッセージが出るよね?それもなんかおかしくね?
>>637 わざわざstd::huck::plus_traitsに持っていく意味がわからない。
>>638-639 std::hooksに含まれているテンプレートを部分特殊化してくれって意味。
オーバーロード解決に相当する処理をテンプレートで実装する必要があるから、
現行C++の機能だけで完全に実現できるかは分からんけど、
必要ならコンパイラにいくつか機能を追加すればいい。
>>640 コンパイラに koenig lookup を追加すればいいってことだな。
642 :
639 :2006/05/25(木) 02:39:06
>>640 その意味はわかるけど意図が判らない。
直接operator +を特殊化すればよいのではないかと思った。
>>637 これはこれで一時期は真剣に考察されていた案ですけれど,
結局「分かりにくい」ということで一度標準委員会で否決されているんですよね.
swap の場合ですけれど.
特にデフォルトがない hook の場合,特殊化に基づく hook の提供は
exact match を要求する,つまり特殊化したい型それぞれに
いちいち全部特殊化を用意しなければならない
(これは base-derived や cv-qualification まで含めて厳密にやらないといけない)
のに対して, ADL による hook は loose match で済む,
例えば base に対する特殊化が derived に自動的に適用されるような
直感的なあり方に一応適合します.
この議論は関数テンプレートの部分特殊化 (FTPS) が導入されても
基本的な議論の流れに大きな変化はないでしょう.
(というか,クラステンプレートの静的メンバ関数を用いるそもそもの動機は,
FTPS が現行規格で存在しないことの workaround だったはずです)
もちろん ADL による hook の提供の場合も,一般に挙動が非常に予測しにくい,
つまり,名前空間お構いなしでありとあらゆる名前空間を潜在的にぶち破る
凶悪な特性を持ちえることと,一般に汎用プログラミング特有の構文指向な面が
強く出る (hook がどう定義されているか (signature-oriented) ではなくて
hook をどう呼び出したか (syntax-oriented) に意味が左右されやすい)
という非常に大きな欠点を抱えるのも確かです.
>>637 より踏み込んだ議論として,そもそも hook の所有権・所在の
あり方に関する議論もあります.
特殊化に基づく hook の提供の場合,特定の名前空間に hook の所在が
固定されますが,それはそもそも正しいのか?
全く関係の無いサードパティが提供するヘッダとプライマリテンプレートに依存し,
その名前空間を開けて hook を提供しなければならなくなる状況も想定され,
それは本当に正しいのか?という疑問です.
そういう意味では ADL による hook があらゆる名前空間を
潜在的にぶち破る特性を逆手にとって,
「大域の ADL hook 用名前空間 (global ADL namespace) に hook をおく」と
考えることも, hook の所在の中立性という観点からは
あるいは悪くないともいえます.
少なくとも「ライブラリ設計の欠点とその補完としての ADL」という観点は
少し視野が狭すぎるような気がします.
>>642 operator+ には特殊化するべきプライマリテンプレートがそもそもないです.
また,関数テンプレートの部分特殊化が現行規格に存在しないために,
一般にクラステンプレートに対して関数テンプレートを特殊化することができない,
という事情もあります.クラステンプレートの静的メンバ関数を
わざわざ持ち出すのは,関数テンプレートの部分特殊化の
エミュレーションのためだと思ってもらえれば良いかと思います.
>>643-644 > ADL による hook は loose match で済む,
こいつの解決策だけど、
案1: オーバーロードを追加するとき、新しい名前を導入したとみなさないで
部分特殊化と同様に扱えるような構文を導入する
lazyoverload operator+;
namespace std {
...
namespace hooks {
lazyoverload swap;
template <class T, class Alloc> void
swap(std::vector<T, Alloc> &a1, std::vector<T, Alloc> &a2)
{ a1.swap(a2); }
}
}
template <class T> std::complex<T>
operator+(const std::complex<T> &a1, const std::complex<T> &a2)
{ ... }
コンパイラから見ればKoenig lookupとほとんど同じ機能だから、
実装は不可能ではないはず。
案2: typeofなどの機能を導入してオーバーロード解決の機構を テンプレートから活用できるようにする template <class U> struct plus_traits<std::complex<int>, U> { static std::complex<int> plus(const std::complex<int> &a1, int a2) { ... } static std::complex<double> plus(const std::complex<int> &a1, double a2) { ... } typedef typeof(plus(const std::complex<int> &, U)) result_type; }; 実現性がどの程度なのかは分からんけど、可能ならテンプレートの力はかなり増す。
>>646 >>643 さんが指摘されてる、クラステンプレートの部分特殊化による手法の問題は、
class Aに対してstd::hooks::???_traits<A>を実装したとして、
その後AのサブクラスであるB,C,...Zを作成した際に
全く同じstd::hooks::???_traits<B>, ... std::hooks::???_traits<Z>を
実装しなければならないということだと思うのですが。
この点、ADLの場合は基底クラスを引数にとる関数一つで用は足ります。
派生クラスと基底クラスの関係は、
オーバーロード解決では考慮されますが(部分)特殊化の解決では考慮されません。
>>643 のコードを見る限り、operator+(T,T)の部分特殊化として
operator(const complex<T>&, const complex<T>&)を定義しているようですが、
これでは、
>>643 で言及された問題は解決できません。
ただし、ADLがない世界を仮定して、更にlazyoverload云々を無視して
普通のオーバーロードだと考えれば、
>>643 の問題はないように思います。
これは、hook用名前空間を1ヶ所用意して、
特殊な動作は全部そこに書く/書かせるということと同じでしょう。
もちろん名前空間の内部が第三者によって手を加えられる(特殊化ではなく)という問題はありますが。
>>648 普通のオーバーロードだとこれが動かない。
template <class T>
std::complex<T> operator+(std::complex<T> a1, std::complex<T> a2);
namespace std {
template <class T>
struct plus : public std::binary_function<T, T, T> {
T operator()(const T &a1, const T &a2) const
{ return a1 + a2; }
};
}
template <class T>
std::valarray<T> operator+(std::valarray<T> a1, std::valarray<T> a2);
650 :
648 :2006/05/25(木) 14:43:27
>>649 std::plus::operator()内のa1+a2のことを言っていると思いますが、
いまいちよくわからないので、推測しながら答えます。
まず、complexのoperator+が、
plus内部から解決されないことを問題にしているのであれば、
>ADLがない世界を仮定して、
ということです。
もう少し補足すると、ADLがない結果として、
std名前空間内にoperator+がないことも仮定しています。
また、valarrayのoperator+が最後に定義されていることから、
two phase lookupを問題にしているとも推測できますが、
それでも特に問題がないのではないでしょうか?
どこを問題にしてるかを明らかにしてもらえれば、
より有意義に議論できると思います。
651 :
648 :2006/05/25(木) 14:55:55
よく考えてみたら、ADLがない場合には two phase lookupの挙動が変わりそうな気がしてきましたが そこまでは考えていませんでした。
>>650 plusからはcomplexのoperator+は見えるけどvalarrayのoperator+は見えない。
646で書いたlazyoverloadというのはoperator+を全部見てくれという意味。
>>652 一応確認しておきますが、通常のC++における
>>649 のコードの問題点は、
両方のoperator+がstd名前空間内にないことですよね?
>>649 の"ような"コードでは、complexのoperator+もstd::plus::operator()からは呼ばれませんし、
(
>>649 のコード単体ではcomplexのoperator+は呼ばれますが、
std::basic_string等のoperator+がstd名前空間内に定義されてしまうと呼ばれなくなる)
逆に、両方のoperator+がstd名前空間内にあれば、両方ともplusから呼ばれます。
で、本題に戻りますが、
>>643 で指摘された問題点と
lazyoverloadには何の関連があるのでしょうか?
今の段階では、
> ADL による hook は loose match で済む,
という部分を勘違いされているように思えます。
あと、
>lazyoverloadlazyoverloadというのはoperator+を全部見てくれという意味。
の全部というのは、名前空間を無視して全部ということでしょうか?
>>653 >>643 の問題を普通のC++で解決するのが大変or不可能であることは認識している。
で、その解決策として部分特殊化でなくオーバーロードでhookを実現
できるようにする(
>>646 )か、メタプログラミング向けの機能を追加する(
>>647 )
ことを考えた。
> >lazyoverloadlazyoverloadというのはoperator+を全部見てくれという意味。
> の全部というのは、名前空間を無視して全部ということでしょうか?
lazyoverload宣言をした名前空間の中だけ。解決したいのは次の問題。
namespace nnn {
int fff(int) { return 0; }
template <class T> int good() { return fff(T()); }
template <class T> int bad() { return nnn::fff(T()); }
int fff(char) { return 1; }
}
と定義されているとき、nnn::good<char>()は1を返すけどnnn:bad<char>()は
0を返してしまう。テンプレートを定義した時点で見える関数だけでなく、
インスタンス化した時点で見える関数を全部候補にしてくれ、というのが
lazyoverloadの意味。
>>654 標準準拠のコンパイラでは、
そのコードでは、nnn::good<char>()も0を返すはずです。
というのは、point of instantiationの文脈で名前解決を行うためには、
unqualifiedな関数呼び出しで(これはOK)、かつADLを介する必要があります。
しかし、charにはassociated namespaceがないため、ADLが行われません。
その結果、point of definitionの文脈で名前解決が行われます。
というのを昔、
>>643 の中の人(多分)にどこかのスレッドで教えてもらった記憶があります。
ちなみに、
>>643 に対する一つの解決法として
現在、boost.rangeなどで使われているものがあります。
lazyoverloadによる結果と違うのは、
fundamental type用のフックが定義できるかどうかということでしょうか。
>>655 >現在、boost.rangeなどで使われているものがあります。
>lazyoverloadによる結果と違うのは、
>fundamental type用のフックが定義できるかどうかということでしょうか。
あと、フック関数の定義される場所が
1ヶ所の名前空間になるか(lazyoverload)
複数の名前空間にまたがるか(boost.range)ということでも違いますね。
>>655 > そのコードでは、nnn::good<char>()も0を返すはずです。
これですね。勉強になりました。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197 > fundamental type用のフックが定義できるかどうかということでしょうか。
ADLが利用できて、operator以外であれば、フックにダミーの引数を入れて
無理矢理ADLをやらせる手がありますね。
namespace hooks {
struct hack;
}
template <T> int really_good() { return fff(hooks::hack(), T()); }
struct hooks {
int fff(hack, int) { return 0; }
int fff(hack, char) { return 1; }
}
struct abc {
struct A {};
int fff(hooks::hack, A) { return 2; }
}
lazyoverload を持ち出している方の動機は一応理解できているつもりです. ですが, lazyoverload という提案はあくまで今手に入る 言語の仕様ではないので,これに関する議論は少し避けさせてもらいます. 提案自体に対しても,特に後方互換性の点で色々あら捜しはできるかとも 思いますけれど,それも指摘したところであまり実になるとは思わないので, もうちょっと一般的なことをつらつら書かせてもらいたいと思います. hook をある名前空間に集約するべきか,あるいは あらゆる名前空間(associated namespace)に散在させるべきかは 一般に非常に難しい問題だと思います. 例えば swap という hook を考えたとき(これは現行規格の文言では ADL 経由で発見される hook であるとは明示されていませんが), swap という操作は問題ドメインをほとんど限らない非常に一般的な操作・概念で, 1つの名前空間に集約する方向性はそれほど正しいとは思えない. どちらかというと各ユーザ定義型の associated namespace においておくほうが おそらく正しい. std 名前空間に集約するという方策もある意味中立性が高いので, std 名前空間に swap という hook を集約してしまう考え方もあるかとは思いますが, そうした場合,今度はそれまで考慮されてこなかった新しい hook が登場してきた 場合に,その hook をどこに集約するべきなのかという問題が常についてまわります.
もちろん ADL による hook でも問題はあります. 先の swap を ADL 経由の hook とする場合,あらゆる名前空間において "swap" という名前の非メンバ関数の意味を潜在的に予約してしまいます, これのため,あらゆるドメインで "swap" という名前に対する共通のコンセンサス (つまり2つのオブジェクトの状態を交換するという操作の名前であるという共通認識) が取れるという(楽観的な)前提が必要になります. 実際, swap に対する将来的な規格の方向性は現在のところこの立場のようですが, 一方でこの話を金融関連のドメインで仕事をしている方たちにしたところ, 「swap という言葉は金融関連のドメインではまったく違う意味で使われる (ので swap という名前に共通のコンセンサスが取れるという認識は甘い)」 と異論がきてしまった,という話もあったようです. swap という非常に一般的と思われる名前1つでこの状況ですから, おそらくある名前を全ての名前空間で潜在的に予約してしまう ADL hook のあり方は 一般には非常に受け入れがたい. 現在, Boost.Range などで導入されている ADL hook の名前では, この問題を避けるため,マクロの名前規則を髣髴とさせる boost_ なんて prefix が付いています. しかしこれでは ADL による hook の大きな利点であった 「hook の所在の中立性」をかなり殺してしまっています. 実際,この観点から名前を boost_begin じゃなくて range_begin にしたら? という議論も見受けられます.
ライブラリ設計を考える上でユーザの使い勝手は非常に重要で,
そして hook をユーザにどう提供させるかはまさにライブラリの
インタフェース設計そのもので,ユーザの使い勝手に直結する部分だと思います.
今ここで議論されている方々は造詣が深く,
hook の提供における問題点を把握され整理されておられるので,
>>646 >>647 >>657 といった手法も自然に受け入れられ,
各々の手法の長短も理解されておられますが,
世間一般の大多数から見れば非常に理解しづらい難解な問題であり,
ライブラリ利用者の立場でこれらの手法を利用して
hook を提供しようとする場合,大多数はいわゆるバッドノウハウ,要するに
「関心のある問題の解決に直結しない,不必要に難しい手法と知識」
としか評価してくれないかと思います.
そしてこれはそのままライブラリ全体の評価に直結すると思います.
こういった,特にライブラリを利用する上でのバッドノウハウは
うまく隠蔽できるならばそれに越したことはないかと思います.
ADL hook はもちろん色々な問題は抱えますが, 利用者の立場から見れば,
他の手法と比較しても,次善策としてはある程度妥協できるレベルに
あるんじゃないでしょうか?
Boost.Serialization では,アーカイブのバージョンを指定する引数に
>>657 で示されているような hack を巧妙に隠蔽することで,
two-phase lookup での問題を解決しつつ, hook のためのオーバーロードを
boost::serialization 名前空間に集約させることに成功していますが
(ライブラリ作者の名前から Ramey trick とか呼ばれることもあります),
あのレベルに到達して初めてライブラリのインタフェースとしては
成功と言えるのではないかと思っています.
もちろん,あの手法は非常に特殊な状況で偶発的に成功した例だと思いますので,
汎用性が全く欠けていて応用が利かないのですが…….
個人的にはこれらの問題は C++ の言語規格あるいは C++ のライブラリ設計を原因とする固有の問題だとは思っておらず, (C++ の)汎用プログラミングにおいて非常に重要で魅力的な特性である "non-intrusiveness" を成立させつつ,なおかつ hook をどう提供するか, を考える上でかなり本質的な問題だと思っています. 将来的な言語機能の追加も視野に入れてよいならば,例えば コンセプトに基づく特殊化・オーバーロードといった C++0x での 機能追加があるいは問題解決の1つの糸口になるのではないかと 個人的には思っています.
ドラゴンボールにたとえてもう一回プリーズ
663 :
デフォルトの名無しさん :2006/05/27(土) 10:42:33
神様、宇宙人、人造人間、とさらに強い敵を出すために世界観が滅茶苦茶。 技もどんどんインフレになっていき、何が強くて何がよわいのか、序列や使い方 が良くわからん。つまりドラゴンボール状態。 C++ is Dragon Ballというのは、アメリカのカンファレンスで良く聞くジョークでも ある。
(拍手)
665 :
デフォルトの名無しさん :2006/05/27(土) 17:59:55
よく聞くのかよ
毎日な
667 :
デフォルトの名無しさん :2006/05/28(日) 23:12:30
『ゴクウが教えるC++』という書籍では、継承を説明するのに、サイヤ人←スーパーサイヤ人と いう誰でも思いつきそうな例で説明されているらしい。
例えで説明してもらわなくても、シンプルなソースと実行結果があれば概念なんて直ぐわかっちゃうのに。 例えての説明で一番分かってもらえるのは、既に知っている人なんだけどな。 しかもC++はあまり難しくないと言う罠。
C++の難しさはbetterCとしても使えてしまうところじゃないか? 結局のところ、それでもかなりのことが行えるので、それで満足してしまって C++の本域や可能性を見失ってしまう。 まぁ、STLにしてもほかのBoot(?)にしてもこれらを使いこなせるようになる前に 大概のことは楽にやってのけられるし、 これらを学んでも実践にどこまで投入していいか?の問題もある。 あと、Cの影響力が強すぎてC時代の財産とかが未だに尾を引いているのかもしれない。 (周りの人間との統合性とかを考えるとやっぱり Better Cぐらいが一番能率がいいのかもしれないし。)
>>669 休刊直前くらいのCマガにそれと同じこと書かれてたな。
671 :
デフォルトの名無しさん :2006/06/09(金) 03:28:13
C++がドラゴンボールというのは、なんとか仙人とか何とか王様とか変な権威ありそうな 奴がいろいろ御託を並べるが、実は何か奥が深い物があるわけではない、という点でも 似てるな。
672 :
デフォルトの名無しさん :2006/06/09(金) 16:48:52
MFCで自作簡易レンダリングエンジンって出来ませんか。(IEに依存しない) 何方か方法おしえて>>>
Javaは引数の参照渡しができない とんでもない駄作
>>674 そーゆーこはJava厨が沢山居そうなスレにageで書き込みなさい。
C++のマニピュレータはどこもマネしないくらい最強
あれ使ったことない 難しいというか・・・鬱陶しいというか・・・
アレはどっちかっていうと単にインターフェイス的にもパフォーマンス的にも 駄作(というか失敗作?)だから、みんなにそっぽ向かれただけ。printfマンセー!
まああれはあれで、使いようによっては有用で便利なんだが vector<int> vec_int; ・・・中略 cout << vec_int / "," % 3 << endl; たとえばこれで、vec_intの中身全部を 一行に3要素ずつ( % 3)、カンマで区切って( / "," ) 出力なんてことをやったりできる
ああ↑はあくまで、こういうマニュピュレータを自分で定義したら、という話ね。
そもそもstd::endlもマニピュレータだということを知らない人がかなり多い
ライブラリに優劣があるのは仕方ない iostreamは行き過ぎた抽象というやつかな ファイルなんかランダムアクセスでいいんだよバカやろう 的なのが提案されてる ともかくいまさらbindを取り込むDは不憫
streamの名前の通りに素直に考えた設計だと思うけどね。 iostreamの出力をiostreamで読み込む。これは簡単。 問題は既存のファイルや人が読みやすいファイルがstreamとして扱いやすいかということだろうよ。
iostreamは真似しちゃいけない設計の見本のような気がする。
後のSTLともあまり噛み合ってないからな・・・。
>>679 >カンマで区切って( / "," )
「<<」、「>>」で感性がマヒしてると、こういう
変態的な演算子を定義しちゃうようになるんでしょうか。
templateとBoostで麻痺してるせいか この程度は、きわめて直感的でわかりやすいと 自分では感じるんだが まああれだ、素人はだまってろ
まあでも他人と共同で書くときには控えようかなと思うよ、俺は。
俺も、なんか気づいてみたら趣味で書いてる時と、仕事で書いてる時のコードに とても同じ人物が書いたとは思えないようなギャップが発生している。 ・・・ゴメン、本当は仕事で書いてるコードも基礎部分が極端にトリッキーなコードになってる。
C++にclassって必要なの? structで充分だろ
>>690 そう思うなら使わなければよろしいのでは?
692 :
デフォルトの名無しさん :2007/02/28(水) 06:53:06
CとC++じゃ明らかに生産性が違うよ
693 :
デフォルトの名無しさん :2007/02/28(水) 07:00:11
えっ、そうなんですか、つまり 生産性は C >> C++と
694 :
デフォルトの名無しさん :2007/02/28(水) 21:44:20
C++は再利用性が高くてメンテナンスも容易 オブジェクトを組み合わせるだけでほとんど完成する
C++は1ヶ月も見てないととたんに忘れるな・・・
スクリプト言語からC++に戻ってくると、 通常型とポインタと参照があることに安心する。
あるあるwwww
>>690 十分といえば十分ですね
まったく同じ子とできるわけだから
コンテナクラスの継承マンドクセ
std::vectorとかか? あれは継承するような存在ではないから面倒で当然だ。
>>684 具体的には?
istreamとostreamがiosを仮想継承して
iostreamがistreamとostreamを多重継承しているところとか?
>> と << の気持ち悪いオーバーロードとかもかな。
マニピュレータを新しく作るにしても istream, ostream, iosを修正しなくてもできるの?
>>704 できるよ。
やりかたよくわからないけど。
わからんのに言うなーー
707 :
デフォルトの名無しさん :2007/03/24(土) 18:12:59
C++の印象: 一貫性より無節操さかな。その無節操なところが難解にさせてるね。 無節操だと思うところは、オブジェクト指向にしても、ジェネリック プログラミングにしても同じ統一した法則の元で成り立ってないわけで それが複雑怪奇にさせているという指摘。 オブジェクト指向にジェネリック系の考えを入れてプログラミングを すればわかるけど、よほど注意深く作っていかないとスパゲティになっ てしまう。それだけバグ取りが難解になり易い弱点を持ってるね。 バグ取りだけじゃなくて、コーディングに時間がかかるね。効率的な 作成はまず不可能だと考えていいよ。javaでも最近テンプレート的な 動きがあるようだけど、あれは自滅の方向かもしれませんよ。 要するに余計なところばかりに神経を使って作らないといけなくなる 事がC++の問題点だと思うね。慣れたから大丈夫というレベルを超え ちゃってるんで。
>>707 直行してる概念を組み合わせても混乱は無いはずなんだが。
オマエのプログラムがスパゲッティになったのを誰かのせいに
したいだけに見えるぜ。
709 :
デフォルトの名無しさん :2007/03/24(土) 18:47:09
インターフェイス実装目的以外での継承禁止
707は物事を組み合わせること自体を複雑怪奇になると表現しているように思う。 極論すればいい意味でプログラミングそのものの否定に結びつきそうな感じがする。
C++は10年以上昔から存在し、かつ互換性も保ってきたのだから 文法が煩雑になるのは仕方ない。しかしそれだけ昔からあるのに 未だ高級言語の最前線に居り能力を認められているのは驚くべき事だ。
むしろテンプレートが導入されたときから始まったと言っても過言ではない。 そのテンプレートが出てきたのもARMが出版された1990年頃。 それ以前から構想していたのだろうし、つい最近出てきたようで随分前からあるもんだな。
714 :
デフォルトの名無しさん :2007/03/24(土) 21:50:35
708は相手にする価値がないと判断したから???としたが。
>>711 組み合わせたら複雑怪奇になるのは当然だが、言いたいのはその組み合わせの
ところがぐちゃぐちゃになってる。
テンプレとオブジェクト指向をまじめに組み合わせて作ってみればわかると思
うけど、かなり先の見通しが出来ない限りスパゲティになるのさ。熟孝がどう
しても必要になってくる。スパゲティにしないように工夫して作るのは結構大
変。この辺がわかってない奴がC++で組むと遅いものしか出来ない。実力差がで
易い言語だともいえるが。
また、必要悪なのかもしれないが仮想関数もスパゲティにしている原因だ。あ
れは極力使わないように工夫する必要がある。
テンプレの発想は凄く良いものだがね。
>>714 原因と結果の因果関係が何も説明されてないから、「ふーん」としか思えない。
ダメなプログラマはどんな言語を使ってもスパゲッティを作るし、
優秀なプログラマはどんな言語を使っても良いコードを書く。
それだけのことだろ。
C++は自由度の高さと抽象化のレベルのバランスがちょうどいいんだよね。あれだけ抽象的なプログラムが書けながら低レイヤーでの処理がはっきり見えてくる言語は他にないな。抽象化をしながらそれでいてブラックボックスが限りなく少ないんだよ。自分は好き。 オブジェクト指向とテンプレートを組み合わせるとスパゲッティになるという主張は全く意味が分からない。設計が下手なんだな。
717 :
デフォルトの名無しさん :2007/03/25(日) 11:42:45
>>716 下手なんだなじゃなくて、慣れてないとうまくいかないよって話だよ。
慣れていたって、ジェネリックにする為の穴はかなり作ってしまい易い。
そこは熟孝なしに作れないところで生産性を損なうんだよね。その熟
孝の方向が作ろうとするものよりその周辺にばかり気をかける比率が
高いの。これがテンプレのライブラリの難しくする場所でもある。ボ
トムアップ的な思想だけではうまく作れないものなの。トップダウン
的な発想をしつつトップダウンな作り方が求められるからね。
オブジェクトごとに算術オペレータとかも丁寧に作っていかないといけ
なくなったりしますから、どうしても助長なプログラムになってしまう
し、見通しが複雑になり易い。traits技術とか切り抜ける方法はいくら
でもあるけど、実際に作ろうとするものよりその周辺ばかりに注意しな
きゃいけなくなって、制作のテンポも悪いよ。
C++は自由度は高いけど、複雑なルールに基づいているだけに難しくなる。
わからないのは頭だけで考えているからだよ。実際にテンプレートライブ
ラリを設計してみたらいい。いろんな注意点に気がつく事になるよ。
他の言語との比較は荒れるもとなので意図的に控えてるけどね。
718 :
デフォルトの名無しさん :2007/03/25(日) 11:44:41
トップダウン 的な発想をしつつトップダウンな作り方が求められるからね → トップダウン 的な発想をしつつボトムアップな作り方が求められるからね
代数的なクラスでもない限り演算子オーバーロードは使わないと思うが
> 他の言語との比較は荒れるもとなので意図的に控えてるけどね。 一連の書き込みから、どうも何か煽っているように見えてたんだけど、 荒れるのは嫌なのね。いったい何がしたいの?
>>717 traits技術を駆使してテンプレートライブラリを設計して
いろんな注意点に気がついてしまったか
まずその注意点を書くべきだぞ
汎用的なコードを書こうと思ったらいろいろ気をつけなきゃいけなくなるのは あたりまえなのにねぇ。
723 :
デフォルトの名無しさん :2007/03/25(日) 13:01:52
>>719 stringを含めたクラスでクラス同士の足し算利用するようなことは
十分使えるものなんだが。そんなところまで意図して書いている。
かけ算までは利用する事はあまりないと思うがね。
やはり実際に作ってみないとわかりにくいのかもしれないね。実際に
テンプレートクラスを1から作ってご覧。
>>720 何がしたいの?ってこのスレのタイトルに対しての見解を書いてるだけ
だよ。仮に、C++賞賛スレならばこんな事は書かない。辛口なこと?は
十分受け入れられるスレだと判断したからだ。
同じルールの元で、いろんなパラダイムを持ってきたのではなくて、
つぎはぎの仕方が複雑になってるからだと言ってるわけ、その例が、
オブジェクト指向とテンプレートの掛け合わせの問題を出しているだけ。
C++ではいろんな事は確かに出来るけど、複雑なルールの元で作られて
るために、保守点検も含めていろんな事が難しくなる。それが、C++人
気が廃れてきた原因だろうね。
なんていうか、新しく覚えた手法は全部使わないと気がすまない病気なんじゃないだろうか? ある程度知識欲のあるプログラマなら一度はかかる病だと思ってるけど。 必要なプログラムだけ書いてればいいんだよ。新しい機能を思いついても、 明らかな必要性がない限りやらないほうがいい。 YGANI ってやつ?
批判精神に富んだ青年に traits技術を駆使してテンプレートライブラリを設計して いろんな注意点に気がついてしまわせたC++は 魅力的な言語だと言うことだな
>>723 > オブジェクト指向とテンプレートの掛け合わせの問題を出しているだけ。
最初っから言われてるけど、さっぱり因果関係がわからん。
人に伝えるつもりなら「やってみれ」とかで済まさずに説明してくれ。
説明する気が無いなら長文 age ウザイからチラシの裏にでも書いててくれ。
例えばBoostとか見てみ。何も複雑なことないでしょ? 言語機能を把握しきれなくて複雑に感じるというのなら納得。しかしオブジェクト指向、ジェネリックプログラミングはむしろ構造を素直に記述するために上手く働いてると思うんだけど。さらにテンプレートは最適化にも貢献してる。 同じことCで書こうとしたら大変だよ。
ごめんなさい boostのソース見てて発狂しました
>>723 が"具体的な"例を持ってくるまで待とうじゃないか
まあ文法がひどいというのは納得。ただ機能面で同等なことしようと思ったらC++と大して変わらない言語になるんじゃない?コンパイラ任せの部分が増えると書くのが楽になっても機能面でのマイナスが多少はでるよね。 コンパイラより賢い人間がいるかぎりC++のような言語はなくならないんじゃないかな。
言語仕様でなるべくスパゲッティにならないよう努力してもいいんでない? C++は悪い意味で好きなように書け過ぎると思うんだ。 Javaの多重継承できないとか Pythonのインデントみたいな試みは是非はともかく嫌いじゃない
C++は凡人のための言語じゃないと思うんだよね. 研究心のある人が使えばいいのさ. 大きな自由度を残しておく事で,そこから新しい可能性を見つける事ができるんだよ. Boostのライブラリとか見てるとすごく思うけど,C++はいろんな新しい考え方を生み出す実験台としての役割がすごく大きいと思う. 書いている人の好奇心を煽るとてもいい言語だと思うけどな. 実際にアプリケーションを書く言語として適しているかということとはまた別だけれどもね.
C++の開発動機に"Better C"がある以上、Cとは可能な限り互換性を 保たねばならず、従ってC時代由来のアナクロニズムは除去できない。 ifブロックを中括弧なしで書けないようには出来ないわけだ。 他の新しい言語と比べると酷い言語のように見えるけど、 実際のところ禿が掲げた理念を大前提として考えれば、 今のC++は可能な範囲で望み得る、かなり良いものだと思う。 そもそもC++は大規模オブジェクト指向言語の元祖であって、 新しいパラダイムを開拓しつつも互換性を重視する立場からは古い仕様を変えられない、 そう考えると今までのC++が何か大きな間違いを犯したとは思えない。 C++のこういう点が気に入らないなら素直にDでも使うべきなんだろうと思うよ。
>>733 C++を嫌って自由度を追いかけたら、DかLispに行き着くだろうな。
Dもネイティブコンパイラを持ってるようなLispも速度的には速いですから。
>>1 ってよりか、C++で書かれたソフトってやたら重くね?
オブジェクト指向って重いの?
何も考えないと重くなる。 でもC++自体は重くならずに済むよう努力したほう。 そうでなければC++が普及することは有り得なかったと禿は言っている。
C++が重いんじゃなくって、C++のフレームワークにクソ重いのが多いんでないの? MFCとかQtとか
738 :
デフォルトの名無しさん :2007/04/03(火) 22:44:21
STLを使うと実行速度が10倍に?!
739 :
デフォルトの名無しさん :2007/04/04(水) 00:20:31
Cで書けば、フリーウェアでソースも公開してて Win標準装備のコピーより何倍も早いfastcopyは さらに早くなるのか!? ソース見る限り俺は作った人に「すごいよ、あんたすごいよ」 って言いたくなるソースで、ま、結局のところ頭の良い人 はC++で何か作ろうとするとき頭の中にクラスの設計図が 自ずと浮かび上がってくるんだろうな。
C++でもATLでウインドウ制御すれば瞬発力があるソフトが書けるの。 MFCなどを使うと一呼吸動作が遅くなる。 だから言語の問題じゃない。
ちょっとしたデータ変換ツールを作ってみたら、CでもC++でも殆ど同じアセンブラコードになった。 C++の方がテンプレート関数のお蔭でソース自体は短いのだが。
>>741 禿もCがC++の最大の敵と言っているくらいだし、
Cと同じように書けばCと同じ機械語になるのは当然。
一呼吸とか変なこといってんなよ
何が変なのかさっぱり。 MFC擁護のバイトか何かですか?
言葉が変なんだよ。きっと。
templateを使った時にコンパイラの吐くエラーがカオスにな
Cの方がトータルでみて生産性高いと感じる俺は まだまだC++を使いこなせていない
>>747 C++から入った身としては、そういうことがいえるほどCを使いこなせている人が居ることに驚く(強意表現だが)
すくなくとも、普通に使ってる分には、C++ のほうが適当に作ってても修正とか聞くし、
真面目にやるときも設計の目処が立ちやすいし、少ないコードで楽に進められるし、名前問題含め使い勝っていいと思うのだが、
参考までに、どんな所がCの方が生産性が高いのか教えて欲しい。
俺の感性に合うっていうのかな。 Cでゴリゴリ書いてると魂磨いてるって感じ。
たまにCを使うと、変数宣言がブロックの先頭でしかできないのが苦痛。 地味なところでは、for (int i = 0;とかbool型などがないのも嫌になる。 せめてC99を使いたい。
751 :
747 :2007/04/11(水) 23:09:43
誰だ勝手に答えているのはw
>>748 自分の場合、某悪評スクリプト言語からCに入ったので
関数主体で構造化できるってだけで感動しているレベル。
グローバル変数メインでサブルーチンで直接値を操作するのが
当たり前だったもんで…
とてもじゃないけどCを使いこなせているとすら言えない
C++の(というかオブジェクト指向の)クラスとかインスタンスという概念は
面白いとは思うけどオブジェクト単位でデータと関数がまとまっているよりは
命名規則(型ではなく用途で)をしっかりつけたグローバルな変数と関数を
一元管理した方が把握しやすいっていうか楽に感じる。
オブジェクトで分けるよりはシーンで分けた方が直感的というか。
趣味プログラマとしてはメソッド使わなきゃ属性にアクセスできないみたいな
データの隠避にも大した利点に感じない。
そんな間違いすることあるのか?って思ってしまう。
まぁスクリプト言語に浸りきった弊害なのと
C++をひとにみせても恥ずかしくないレベルまで習得するのが面倒なだけやけど。
constとかstringとか楽なところだけ使いつつスクリプト時代のようにダラダラと
手続き型で書いている。
Cの方がってよりも手続き型の方がって話だ。すまんす
データの隠避は複数人での開発では特に重要 1人だとありがたみを感じないのも無理はないと思う
一月前の俺と今の俺は他人
データ隠蔽とかはブロックごとにファイル分けて 構造体に突っ込むことでまだなんとかなるけど テンプレートのアルゴリズムはもうCではやる気が起きなくなるな。
>>751 それ、全部C++でもできることじゃん。
要は、「Cの方が高い」じゃなくて、「C++である必要が無い」だな。
まずnamespaceから
まずC風に軽く組んで、 「ここの機能まとめたら分かりやすくなるかも」見たいな感じで 徐々にOOP「風」に組み直していくやり方でいっぱいおっぱいですよ
自分も早く再利用可能なクラスをいっぱい作って 実際のプログラムは部品をドッキングさせるだけで良いみたいな状態になりたい
結構気合い入れて「俺ライブラリ」を作るんだけど、 なかなかうまくいかないねえ、こう、なんというか、 「近未来の自分にすんげーフィットする汎用性と機能のバランス」ってやつは。
各種文字列クラスとの相互変換テンプレートだらけで 俺ライブラリは統一性が無い。文字コード含めてわけかわらんよ。 比較関数だけでも20種類はある。
難しいとは思わないけど 無駄に複雑 馬鹿みたい
馬鹿みたいというか 馬鹿が複雑に書いてるんだ でもビャーンのハゲは髪だと思う
禿はインタブーで「わざと複雑にした」っつってる死ね
頭の悪い奴には使いこなせない言語だよな、ホント。 でもこの「頭の悪い奴には使いこなせない」の意味を、頭の悪い奴は理解できない。 そして見当違いの方向に怒り出すw
765 :
デフォルトの名無しさん :2007/04/30(月) 22:07:18
こないだ仕事でJava使わされたけど あまりの遅さと自由度の低さに愕然とした やっぱ自分ひとりで組むのならC++だな
Javaのgenericにはしょんぼりした記憶があるな C++的なものを求めるのが間違っているんだけどさ・・・
boostがやばすぎるぐらいに便利だからなぁ・・・ 逆にC++より簡単な言語ってないんじゃね?って思えてくる
boostって何がそんなに良いの? 導入すっかな
std::for_each(r.begin(), r.end(), f);がboost::for_each(r, f);と書けるようになったり、 std::bind1st. bind2ndより見た目わかりやすいbindが書けたり、正規表現ができたり。
770 :
デフォルトの名無しさん :2007/05/03(木) 08:56:18
>>768 少なくとも言語マニアの素養がある椰子には
boost::lambda, boost::function →関数型パラダイム
boost::mpl, boost::preprocessor →メタプログラミング
boost::spirit →構文解析
あたりは垂涎もの。使ってるとJavaとかC#ですら塵に思えてくる
そんなの無くても不自由しねえよって人でも
スマートポインタとかは確実に有用
lexical_castやpolymorphic_downcast、numeric_cast、noncopyableあたりも地味に便利
772 :
768 :2007/05/03(木) 10:40:46
うむ ありがとう 何を言ってるのかさっぱりな漏れにはまだ早いことは良くわかった。 ようやっとSTL使い始めたばかり
コンパイル遅すぎなんだよ糞が
何のための分割コンパイルだ、プリコンパイルヘッダだ
速度なんてボチボチ、イラネな世界になってきたから Rubyとかで良いんでない
最近は専門用語が増えすぎ。 あーぎゅめんとでぃぺんでんとねーむるっくあっぷ かりおすりーりかーりんぐてんぷれーと えんぷてぃーべーすおぷてぃまいぜーしょん えたーなるふぉーすぶりざーど
クトゥルーさげ
いあ いあ はすたあ!
全部の機能を使うのはたいへん
C++のどこがBetterCなんだ むしろWorseCだ
ローカル変数宣言がブロックの先頭に縛られないこと 特にforなどで変数宣言できること inline関数 constで定数宣言できること 強力な型安全性の保障(ベターCとして使うならvoid*から他のポインタ型への暗黙の変換まで禁じられるのはきついが)
>>781 最後以外は C99 で十分だな。
改めて C99 と比べると、
- restrict
- __VA_ARGS__
- stdint
- 複合型リテラル
- 要素指定の初期化
とか、いろいろ抜けてるので十分 WorseC と呼ぶに値する。
>>780 使う人間のレベルによっては、変わるかもしれないな。
仕様としてC99が充分だとしても C99のコンパイラ自体がまだまだ普及してないというのが、一番の大問題。
gccにicc、Sunのccもc99に対応していて、これでも普及していないと言い張るとはDozerはこれだから…… つーか、M$儲というべきか?
で、「世間一般の人」の中で、そのDozerとやらの割合はどれほどですか?
今はもう、理系の大学のプログラミング言語の課程ですら Windowsを使う方がずっと多いでしょ。 昔の人はSunとかで覚えたんだろうけど。
世間一般の人はプログラミングなんてせんなぁ。
gccもiccもWindows版があることを知らないのでは?
で、そのMingw等で作られたアプリケーションの比率はどのくらい? もちろん、VBやdelphi等を除いた、C/C++の中での比較で良いけど。
>>788 「世間一般の人が使っているOS」をコンパイルするコンパイラや
「そのOS上で動くアプリケーション」をコンパイルするコンパイラは
C99に対応してますか?
一般じゃない人(大学の教養課程は一般の人は通らないのですね)は、
betterCのコードをコンパイルする時に
「多数のアプリケーションが使っているC++コンパイラ」を避けて
「該当する環境ではかなりマイナーなC99コンパイラ」を使うべきというわけですね?
俺は
>>781 の中では、最後の型安全保障が一番重要だと思うのだけど
>>785 君が海胆糞erか犬糞erか知らんが、職業マは
そんなもんだけで喰っていけるわけじゃない。
媚びへつらいと責任転嫁で喰うのが一般的。
C99ってconstが定数になるの?
>>793 Windowsで、VisualStudio使ってiccでコンパイルしてますが何か。
お前が何をしていようが、誰も何も思うことなんて無いよ。どうでもいい存在だもの。
visual studioからgccとかicc使うような環境作れるんですか?
gccはともかく、iccはリンカがないからVisualStudioと連携させざるを得ない。 ついでに言えば、誰もやりたがらないだけでgccもVisualStudioから使える。 #つーか、まさかVisualStudioがコンパイラだと思ってないよね。
あれ、Win上のiccってプラグインだよね。 で、もしかして、コンパイラに対するアドオンじゃなくて完全に入れ替えちゃうわけ? gccが使えるってんなら、gccはその通りだろうけど。 つまり、インテリセンスとかのIDEのメリットって奴が活かせなくなっちゃうわけ? (だって文法変わるしpragmaやifdefだって変わってくるし) ていうか、必死にgccを主張して頑張ってる人は 「C99とC++のどちらか」といわれた場合にC99を選択するのかね。 俺は100%間違いなくC++の方を選ぶけど。 OSSなんかで移植性優先でC89ってのはいくらでも見つかるけど C99のメリットなんてどの程度あるのかね。 いや、頑張ってずっと「betterCとして使うなら、そんなことはC99でも出来るからC++は要らない」 と言ってるくらいだから、C++を避けてC99にする方がメリットがあると思ってるんだろうけどさ。 あ、どんなメリットがあるかなんて、別に書かなくていいよ。 「大多数の人にはC++(のbetterCな点)で充分」なことは判りきってるんだから。
いや、俺だって、「C99だったら楽なのに」と思うことはあるよ。 配列の要素数が定数じゃなくていい、なんてのは(std::vectorを使う)俺には必要ないけど 可変長構造体が公式に認められたこととか、 あと、<stdint.h>はあったら随分楽になるとは思う。 (もちろん、多くの非C99環境でも、<inttypes.h>があるから大抵は足りるけど 標準Cでは非公式だから、無い環境のことを考えて#ifdefを使った自前ヘッダを用意しなきゃいけない) でも、それでもC++のメリットに比べたら、C99のメリットなんて微々たるもの。 その上「C++が使える環境(処理系)」が「C99が使える環境(処理系)」よりずっと多いのだから 「C99でも出来るからC++は要らない」なんて、俺にはとても言えないね。
> 必死にgccを主張して頑張ってる人 > 頑張ってずっと「(略)C99でも出来るからC++は要らない」と言ってる 妄想乙
>>784 以降の人も、同一人物か同じ意見の人でしょ。
Windowsがどうのと言ってる人。
>>804 やっぱり妄想乙。行間に何か見えてしまう人なんだろうか。
煽っている人の方は単発でピンポイントで突っ込んでるだけなのに、 一人でそれを真に受けて顔真っ赤にして反論しちゃってるんだろうな。
808 :
デフォルトの名無しさん :2007/06/21(木) 09:30:24
じゃああげようよ
いや、俺には
>>785 みたいな負け惜しみというか捨て台詞というのが笑えるんですけど。
現実をあえて無視して、必死になってとりつくろってるし。
C99の、普及していないという最大の欠点を指摘されてよほど悲しかったのか 何故かWindows批判までして、でもWindowsでも使えると反論してみたり。
それが信者というもの
>>806 というより、誰が誰なのか決め打ちでもの言ってる奴はどれも妄想にしか見えん。
>>813 ライブラリ名の時点ですでにカオスなんだが・・・
ドキュメントのビルドの仕方が分からなくて手つけてないぜ…
難しすぎる。 JAVAの方が生産性高いらしい。
再帰降下型パーサだな。 実行部分はスタックマシン。 これはもうパターンみたいなもんで、自分で一回作ったことがあればほぼおんなじ構造だから大体わかる。
>>816 1行目はただの感想だろうからいいが、
らしいなんて憶測でモノを語るなよ。
「らしい」は憶測ではなく伝聞を表す表現ではないか、というのが一つと、 憶測がまずいのは、それが事実のように書かれた場合であって、事実を語っているわけではないことが 明らかに文面からわかる場合は、別に語ったっていいんじゃないか、ってのが一つ。
横から失礼。 「らしい」は伝聞じゃなくて推量を表す表現だよ。 推量の基になった外部情報が伝聞という事はあり得るけれども。
憶測でも自分の偏見でもここで語る分には何の遠慮も考慮もいらないと思う。 ここは「そういう場」であるんじゃないかな。
つまり、ぬるぽOKという事ですね?
824 :
816 :2007/09/01(土) 06:13:18
ちょwナニこの超展開 流石マ板 書いたときの意図は伝聞らしい
>>824 >JAVAの方が生産性高いらしい。
伝聞の助動詞は「そうだ」だよ。
→JAVAの方が生産性高いそうだ。
>書いたときの意図は伝聞らしい
自分自身の意図を推量する事は無いんだから「らしい」は使えないよ。
んなこたーない。使えるらしい。
いやらしい
推量でも伝聞でもいいが、理由も続けないと有益な議論にならないじゃん。 2chでそんなことを期待するほうがあほですかそうですか。
自分が何もしないのに場が勝手に有益になるのを期待するのは確かにあほだね。 でもそれって2chに限らないよ。
一般論としてJAVAの方が習得が容易だといわれているんだから JAVAの方が生産性が高いって話 まぁ後からでた言語の方が生産性高いのは当然だろうけど 統計取ったのか?とか突っ込まれる悪寒
ごめん マ、ム、は回転させると同じだからよく間違えるんだ。 母の胎内のようだ
>>830 > 統計
「"言語名" 人材募集」でググったのが統計になるらしいぞ。
2ちゃんで見たから間違いない。
834 :
デフォルトの名無しさん :2007/09/03(月) 10:44:30
C++は難しくない。ややこしくて複雑なだけ。 その複雑さを理解してだけで得意になってる馬鹿もいるし
刃物は危なくない。切れたり刺さったりするだけ。
*気を付ければ*
もちろん安全装置だっていろいろあります。
C++何年も使ってたのに1年ブランクあるとと書けないな Cならそんなことないのに
C++に不足してるのは名前付き引数だな。 オプション引数の順番いちいち覚えなきゃいけないとか、 テンプレート持ってる割に古臭い。 boostのいびつさと言ったら。
それね、検討されたらしいんだ。 でも、新しいパラダイムが来るわけでもより型安全になるわけでもないとか、 関数を引数名の分だけ呼ぶ側と呼ばれる側の束縛が強くなるとか そもそもそれが欲しくなるほど引数が多いなんて下手な証とか、 反対意見が多くて却下されたという過去があるんだ。 参照:D&E 6.5.1 キーワード引数
その割にはC99にはあったような気が……
名前付き初期化子のこと?配列と構造体限定でよければ確かにある。
↑アホ
↑ニンニク
名前付き引数? 仮引数に変数名つけるじゃん
と思ったら順番関係なくなるのか それはいいな
Python使ってるとキーワード引数の便利さはよくわかる。 C++でもクラステンプレートのPolicyとかでは出来るのにね。
boost.paramいやなんでもない
boostってまだ標準ちゃうしなぁ
テンプレートのチューリング完全性が意図したものではなく のちに発見されたものだというのがC++の複雑さを如実にあらわしてる その複雑さの果ても解明されようとしているが C++0xが新たなカオスを持ち込んでくれる 好き物プログラマーとしてはたまらないね
templateでエラーの嵐に襲われて思いついたsage I am the bone of my type-parameter. 体は型で出来ている Class is my body, and tyepname is my blood. 血潮はclassで 心はtypename I have created over a thousand compile-errors. 幾たびのコンパイルエラーを超えて不敗 Unaware of export. ただ一度のexportはなく Nor aware of inline. ただ一度のinlineもなし Withstood pain to create many templates. プログラマはここに孤り waiting for compiler's error エラーを前にキーを叩く I have no regrets. This is the only template. ならば我がtemplateに意味は不要ず My whole life was "unlimited type parameters" この体は無限の型で出来ていた いくぞコンパイラ――――エラーメッセージの貯蔵は十分か
タイプミスマッチや型候補なしのエラーの嵐は、conceptが導入されれば緩和される。
853 :
デフォルトの名無しさん :2008/01/21(月) 20:41:39
C++を難解にしてるのは、めったに使わない機能や、 よく知らずに使うと危険な機能がいっぱいあるから。 それらの機能をなくしてしまえば、いい言語になるのじゃない? ・・・あっ、それがJavaか・・・
Java厨こんなところろにまで出張乙
C++を難解にしてるのは、めったに使わない機能や、 よく知らずに使うと危険な機能がいっぱいあるから。 それらの機能をなくしてしまえば、いい言語になるのじゃない? ・・・あっ、それがC#か・・・
C#厨こんなところにまで出張乙w
C++を難解にしてるのは、めったに使わない機能や、 よく知らずに使うと危険な機能がいっぱいあるから。 それらの機能をなくしてしまえば、いい言語になるのじゃない? ・・・あっ、それがCか・・・
C厨こんなところにまで出張乙w
C++を難解にしてるのは、めったに使わない機能や、 よく知らずに使うと危険な機能がいっぱいあるから。 それらの機能をなくしてしまえば、いい言語になるのじゃない? ・・・あっ、それがDか・・・
D厨こんなところにまで出張乙w
2chを難解にしてるのは、めったに使わない機能や、 よく知らずに使うと危険な機能がいっぱいあるから。 それらの機能をなくしてしまえば、いい言語になるのじゃない? ・・・あっ、それが1chか・・・
ニコ厨こんなところにまで出張乙w
もはやなにがなにやら
>>860 そういう言語を目指してたはずのJAVAやC#は同じ道を歩んでるしな
よほどなオプソ開発者でもない限り、大幅仕様変更や削減は難しいからねぇ・・・
オマンコを難解にしてるのは、めったに使わない大陰唇や、 よく知らずに使うと危険なクリトリスがいっぱいあるから。 それらの機能をなくしてしまえば、いいオマンコになるのじゃない? ・・・あっ、それがアヌスか・・・
アヌス厨こんなところにまで出張乙w
なんなんだ
純粋に言語としては C++が際立ってJavaやC#より難しいとは もう言えないんじゃないか DにいたってはもうC++より難しいのではw
JavaやC#は、大規模な標準ライブラリが付属してるから簡単に感じるんだな C++だと、標準ライブラリの提供する機能が少なすぎる 設計は美しいんだがな。STLとか。
C++もBoostが(ゆっくりとだけど) よその言語が持っているようなものを(ようやく)用意し始めている。 スレッドとかシリアライぜーションとかネットワークとか。 XML読み書きも欲しいな。
domやsaxならいっぱいあるだろ
拡張可能な暗号化・ハッシュ・圧縮インフラが標準で欲しいな
C++のめったに使わない機能ってなんだろう virtual継承とかprotected継承ぐらい?
export asm template template valarray ダイグラフ
asmは結構使ってるなぁ 俺のレベルって低いんだなw
asmはCPUをハードウェアレベルでいじりたい時に使うよな
>>874 C++にstream入出力ライブラリは標準でないの?
VC++なんで__asmです。
template template は使えない期間が長過ぎたんで道具箱に入ってなかった でも明日から使うよ
template templateは結構枯れている印象
883 :
デフォルトの名無しさん :2008/02/18(月) 18:59:10
Cとの互換性だのメモリ管理だのは実のところ難しくない。Objective-Cを見よ。 俺から見たC++の難しいところ。 (1)例外安全 例外処理はどんな言語でも難しいが、GCもfinallyも無いから気を使う場面が多くなる。 (2)オーバーロードと関数template 暗黙の型変換が必要な命令型言語の世界に型推論を持ち込んだら複雑になって当たり前。 (3)iostreamの細かいところ ああいうstatefulで多彩なエラー処理が必要なクラスライブラリは、 規格をごりごり書くより参照実装を出す方が実際的だと思う。
>>874 それらの機能は時代とともに変化するし、ターゲットによって最適な手段が異なるので
C++のように幅広く利用される物に標準として搭載するのはいかがなものか、と思う。
ハッシュは採用されるだろ
>>874 が言ってるのはたぶんMD5とかSHA-1のような暗号的ハッシュ関数のことだと思う。
ライブラリ化するのはポリシークラスや関数オブジェクトをパラメータ化すれば容易いし、 拡張も容易だろうけど、時代の趨勢に標準が追いつかなそうだな
C++みたいに組み込みからサーバまで使われるようなものに、 ハッシュや暗号化のようなコスト、耐久性にいろいろとバラエティの取れるものを標準搭載してもなぁ、って気はする。
個人的には、フリー以上ホスト未満の分類をもう1つか2つ増やしてもいいと思う。
CRC、zlibくらいはあってもいいんじゃないかという気は
ライブラリを独立した規格にすればいいのにと思う。
というかそういう声が多かったからBoostができたんじゃないかと
そしてTR1へ
言語の細かいとこにあまり神経使いたくないね。 設計とかテストとか神経を使う重要なとこは他に一杯あるんだから。 重要でないが細かいとこに注意を向けるあまり肝心のことが抜けてるってのは ありすぎるほどある。 思い当たるだろ。 たぶん、個人の注意力の総量は一定なんだろう。 あるとこに注意を向ければ別のとこがおろそかになる。 それだったら重要度の高い部分に優先的に注意を向けたほうがいい。 しかし C++ だとこれが出来にくい。 言語に落とし穴が多いからいやでも注意しなければならない。
>>894 落とし穴というのは適切な比喩でないな。道路脇の崖とでもいうべき。
道に慣れてる人間にとっては危険でもなんでもない。
897 :
デフォルトの名無しさん :2008/03/09(日) 00:24:54
初心者的な疑問なんだけど、 クラスとかからメンバを呼び出すときに .を使ったり->を使ったりするのって、具体的にどんな理由で2種類あるんでしょうか? ->を使うところをすべて.で済ますようなことをすると、ソース的にありえないところが出てきたりするのですか?
class foo {public: void memFunc();}があるとして、foo * bar = new fooしたときに bar->memFunc()する代わりに(*bar).memFunc()することに何の躊躇いもないならば、 どうぞご自由にアロー演算子を使うことをおやめくださいませ。
struct A foo; foo.val1 = 1; strct B * bar; bar->val2 = 2; // 初期化していないポインタへの演算ざけどそこらへんは気にせずに・・・
そうじゃなくて、なぜ実体/参照は.で、ポインタは->なのか、ポインタにも.でアクセスできる文法にしなかった理由は何なのか、ということじゃないかな。
それはつまり class Foo = new Foo(); という文法を認めろ、ということか・・・
何書いてんだ俺w酔っ払いすぎだwww foo f = new foo(); という文法を認めろ、ということか・・・ に訂正_| ̄|○
T1 p;のとき *p がT2&を返すような実装をしてると p.aの意味が不明になるでわかるかな
>>904 演算子オーバーロードできるC++で破綻するのはわかるんだけど、.演算子と->演算子はCからあるよね。
Dでは左辺がポインタでもそうでなくても常に . 択一だったはず。 文法上はそれでも成り立つのはわかる。 でもなんでCでは区別するのかという答えは出てこないけどな。
演算子をそう定義したから、としか言えないのかな。 ドット演算子はポインタでない変数のメンバを参照するもの、という定義があって、 これをポインタ変数に適用しようとすると、dereference operatorの機能も入るから、 演算子を同一としてはいけない、と。 ドット演算子を「変数のメンバを参照するもの」と定義すれば、ポインタでもそれ以外でも 使えるようになるけど、Cではそれをしなかった。 そう考えるとC++のoperator overloadingって結構変態的な機能なんだね。
そうだなCでだと、p.a.a と p.a の区別をどうするか って言えばわかるかな
あんまり自信ないけど 要は誤って別の型にキャスト->ウヒャ を嫌ったんじゃないかと言う気がする
当時のコンピュータとコンパイラの性能とあわせて コスト的に違うものだという意識が働いてたんじゃないのかね。 a = aa.bb.cc.dd と a = aa->bb->cc->dd じゃ 生成されるコードが全然違うからね。 と思ったが、配列とポインタの扱いを考えると違うか。 a->bが(*a).bという記法の省略であるというのはどこでも説明されているけど。
つーかメンバのポインタだけ -> なんて記号使っておきながら なんで他のポインタはアスタリスクだらけなんだろうか
>>910 古い本には「ポインタを何回たぐる」といった表現が頻繁に出てきて、
間接アドレッシングのコストが強く意識されていた様子が読み取れる。
だから.と->でのコストの違いは大きな要因だったと思うよ。
ましてstructやunionは入れ子にしてaa.bb.cc.ddみたいに
アクセスするのが前提っぽい設計だし。
Cの基本は値渡し。 構造体と配列は値渡しができないのでポインタ渡し。 そこで、構造体と配列については簡易にアクセスできる演算子を作った。 とか言ってみる。
>構造体と配列は値渡しができないのでポインタ渡し。 ???
>>914 配列は値渡しできないだろ。
K&R時代は構造体も値渡しできなかったよ。
いや、配列はわかってるよ。構造体もできない時代があったのか・・・失礼。 VBでbyvalで渡せなくて「なんだこの糞言語は!」って思ったこともあったなぁ・・・
正確には「配列の先頭アドレスを値渡し」だな 配列の中身は参照渡しに見えるけどな
むしろ、Cは全てにおいて値を渡す その値は変数の中身だったり(変数や配列を参照する)アドレスだったりする と考えるのが正確ではないか
>>918 その程度のことをもっともらしく語るなw
構造体、配列はその中身を渡したくても渡せなかった。
本当は中身を渡したくても、不本意ながらアドレスを渡すしかなかった。
だから[]や->を作ったと言うことでしょ。
その意味では、「全てにおいて値を渡す」ってのは低レベルの言語では極当たり前の話だよね。 プロセッサにおいて、何がしかの値以外のものを渡すって概念がないんだから。
でもこの基本中の基本が理解できなくて、 ポインタを覚えようとしている初心者は発狂する 解説書が悪いんだが
typedef class foo{ ..... }bar; bar *ptr; ptr=new bar(); (*ptr).some_member=1; (*ptr).some_methode(); とかしても、正常にコンパイル出来て走るのに 型宣言の時 ptr -> bar; という書式で宣言できないのは、もしかするとちょっと問題かも知れませんね。型 変数という宣言時の並びを遵守してないという文句は <-も 認めて bar <- ptr; というようにするわけです。 そうすれば、ポインタは2通りの表記法(* ->)が使えるということに なって表記上の柔軟性が増加するわけです。*表現は算術演算の*と まぎわらしい場合があって多用されるとウザい場合が確かにありますね。
昔、Cマガだったか、operator < とoperator -を定義してop<-methodを実装するよーな 話があったような・・・
=>と->があって+>が無いのはおかしい と一瞬思ったがそもそも=>なんて無かった
op>-.-<qo;
・(中黒)やx(エックス)ってオペラントにはならんよな 内積と外積をですね。あと|A|とか
そもそも中黒はASCIIに無いだろ
C/C++で使われない記号ってある? キーボードをざっと見渡して$と@はソース上には出てこないかなと思ったけど・・・
-> =|> ===||> だんだん貫通力が上がっていくぞ!
$もつかえるよ
>>894 ポリモーフィズムが実行されるために、オーバーライドする関数にはvirtualをつけるべき
オブジェクトスライシングが起こるからスーパークラスの変数にサブクラスの変数を入れないようにすべき
例外を投げる時はポインタではなく値で投げるべき、受ける時はオブジェクトスライシングしないように参照で受けるべき
メソッドの実引数の値を変更したくない時で、組み込み型の場合は値渡しで、そうでない場合はconstリファレンスで定義すべき、
メソッドの実引数の値をメソッド内部で変更したい時で、組み込み型の場合はリファレンスで、そうでない場合はアドレス渡しで定義すべき…
意識的にそうしないという選択ができるという利点はあるのかもしれないけど…
こういうことに気を使いながら、処理内容の方に注意の力点を置いて実装…自分にはムリだ('A`)
>>934 >メソッドの実引数の値をメソッド内部で変更したい時で、組み込み型の場合はリファレンスで、そうでない場合はアドレス渡しで定義すべき…
逆じゃないのか?
C++の参照渡しキモ杉
>>935-936 その区別、意味あんの?
呼び出し元のオブジェクトいじってほしいときは全部参照渡しでよくね?
> ポリモーフィズムが実行されるために、オーバーライドする関数にはvirtualをつけるべき C#もそうじゃない。Javaはそうじゃないけど。 > オブジェクトスライシングが起こるからスーパークラスの変数にサブクラスの変数を入れないようにすべき 基底クラスのコピーコンストラクタ・代入演算子はprivateにしろ。 これはこれで意識しないといけないことだけどさ。 >例外を投げる時はポインタではなく値で投げるべき、受ける時はオブジェクトスライシングしないように参照で受けるべき 受けるほうはともかく、投げるほうに意識する必要あるか?
ポインタで例外を投げるってのは、 throw new Exception(hoge) って事だから
うん。何も考えなかったら、throw Exceptionって書くだろ。 Java/C#のくせでついうっかりってならともかく。
942 :
934 :2008/03/15(土) 22:02:44
元ネタは詳説C++です。
>>938 まず、コスト的にはリファレンスでもポインタでもそれほど変わらないということがあって、
組み込み型の場合、メソッド内で変更可の場合は引数をポインタとすることで、
変更不可の場合の呼び出し
f(a)
変更可の場合の呼び出し
f(&a)
となり、呼び出している箇所を見ることでf()が引数の内容を変更するかどうかのヒントを得ることができる
というのがその理由です。まあ好みの問題かもしれません。
後関係ないけれどNULLを渡す可能性がある場合はリファレンスではなくポインタにしなければならない…ってのも考慮しなきゃいけないですね…
>>939 コピーコンストラクタを作るのが面倒で、じゃあポインタ渡しすればいいじゃんと思ったりとか…?
自分はJava一辺倒なので、C++のプロジェクトに放り込まれたら慣れるまでは落とし穴にはまりまくりそうです。慣れてもどれか1つ忘れてポカしそう…
C++でバリバリコード書きまくるというのには憧れるんですが…。
944 :
デフォルトの名無しさん :2008/04/03(木) 18:43:11
顧客より保身のほうが大事なヤツなんていねーよ 馬鹿じゃねーのwwww
この世に馬鹿がいることがわかってるなら、「いねー」なんて口が裂けても言えないはずだが。
社会保険事務所とかに行くとそんな感じの人が一杯いるよ! ><
>>943 つ CopyConstructible (20.1.3 [lib.copyconstructible])
ほしゅ
必死に時間や金かけてC++学んだ連中には悪いが、俺もC++はゴミだと思う。 習得に時間かかりすぎ。コードの可読性低すぎ。バグ産みやすすぎ。 自由度高すぎて他人のコードが理解しずらいったらありゃしない。 そのうえ未だにSTL周りなどコンパイラの互換性すら怪しい。 言語仕様の設計思想は理解できなくもないが、業務では使いたくない。 趣味で使いたい奴だけが使う言語にとっととなりさがって欲しい。 忌々しきStroustrup。
951 :
デフォルトの名無しさん :2008/09/09(火) 19:11:27
業務で使うならC++ 日本語つかうのに、言語学から始める必要はない STLが怪しいなら使うヘッダとコンパイラを統一して問題がないという判断の出たやつ仕えよ
>>950 こういう事を言う奴に限ってC++使った事ないんだよな
× 使った事ない ○ 使えるようになる前に挫折した
なんだそうか 単に頭悪いだけじゃん
STLの互換性が悪いというあたりから挫折した時期がわかるな
C++はそのあまりにHENTAIチックに入り組んだ構造がたまらなくおもしろいんだよ〜。超遊べるよ〜。
>>955 ここ5年くらいの間にC++始めた人間だと、
ニュアンスがよくわからないだろうな。
>>957 まぁ、もう歴史の闇の中だよなその辺の事柄はw
今はもうわざわざSTLPort入れたりしなくていいんだぜ、いい時代じゃないか
STLportがtr1に対応してないと話にならない時代になってきたな
あの・・・うちまだVC6なんです・・・
窓から投げ捨てろ
>>956 同意ですよ
C++の変態コードのレベルは果てが見えない・・・
最高だ・・・
そんじょそこらの素人を黙らせてしまうようなコードを
書けたときには快感すぎてしびれる・・・
この言語はまさしく神
そしてLispのマクロの変態さを見たらどう反応するか。
2chに居ると誰もが使える言語だと錯覚していたが C++使っているというだけで驚かれることに驚いた。
ずいぶんレベルの低いところにいるんですね。
966 :
デフォルトの名無しさん :2008/09/11(木) 11:49:49
うちで販売しているパッケージはほとんどがvc製だから、 しーぷらできませんじゃ話にならんお。 もっともテンプレートマジックは敬遠されるけども。 最近はJava製品も手掛けるようになったけど、 swingは社内的にも客的にもうけがわるいw
C++で書いてCより生産性上げられる人材なんてそうそう集まらんしな。
968 :
デフォルトの名無しさん :2008/09/11(木) 19:00:05
C++のほうが生産性が高いのは当然 そうでないやつは給料泥棒かアマチュア学生
969 :
デフォルトの名無しさん :2008/09/11(木) 19:03:25
Windows (GUI) プログラム、DirectXプログラムに比べたらC++の文法など大したことがない。 STLやオブジェクト指向は強力でバグが出にくい設計になっている。 利用する側としてのバグね。もともとあったら知らんが。
>>968 同意なんだが現実はそうはいかんぜ。
今度のプロジェクトで
「構造体とかポインタとかわかるか?
なら○○よりは上だな」
って言われたぜhya!!
971 :
デフォルトの名無しさん :2008/09/11(木) 19:15:05
すくなくともSTLは、標準のC言語よりも、易しく生産性が高いぞ。 とりあえずSTLで作っておいて不都合が出たら、C言語やアセンブラやAPIをいじくればいい。 機械に近いほど難易度が増すのが普通だろ。 機械語よりアセンブラは易しく、アセンブラよりC言語、C言語よりC++が易しいはずなんだよ。 わざわざ難解な言語つくっても意味がない。 利用者はすべてを習得する必要はない。 C++の文法のほとんどは、STLを実装するためにあるようなもの。
>>971 高級言語になれば単純に難易度が下がるのか?
単純に文法レベルでの話ならc++よりよっぽどcやasmの方が覚える事も
少ないし、習得も早いと思うぞ。
973 :
デフォルトの名無しさん :2008/09/11(木) 19:30:21
難易度を、同等のものを生産するのにかかる労力で測った場合。
なんだか、「漢字は何万文字もあるけど、アルファベットは 26文字しかないから、漢字やめようぜ」みたいな頭悪さを感じる
>>974 習得工数と実際にやる内容を天秤にかけたら
漢字を捨てるのも十分ありじゃね?
仕事の度に漢字を勉強しなおすならそうなるな
習得の難易だけで人々の使用言語が決まるのならば、 世界標準語は英語ではなくエスペラント語になっていただろうな。
>>975 言語の習得にかかるコストを「工数」という形で定量化して見積もっている
会社ってあるの?
>>978 や、そこまで厳密な意味でいったわけでもないんで突っ込まれても困るが。
「手間」でもいいよ。
今のプロジェクトC++で書かれているんだけど
1つのクラスに5000ステップくらいの長編小説が書いてあってそれを保守せんといかん。
C++がどうとかいう以前の問題の気もするが…
以前の問題ですな。
とりあえず勃起する
俺の裸みて鎮めろ
>>979 それに近いことは、やる場合もある。
たとえば、ある機能を使うときにまたは機能の選定とかをやるときに、
これを採用すると学習コストがかかるから、ここはやめて。。。みたいな。
あと、チームの何名かを研修に参加させるために、それを見積もったりとかさ。