C++相談室 part139
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。 !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part137 (正しくはpart138) http://mevius.5ch.net/test/read.cgi/tech/1535353320/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.103【環境依存OK】 https://mevius.5ch.net/test/read.cgi/tech/1530384293/ ■長いソースを貼るときはここへ。■ http://codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ http://www.bohyoh.com/CandCPP/FAQ/ (日本語) ----- テンプレ ここまで ----- VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured >>602 1つのコンパイル単位内でそれはないだろ。 >>605 の一番近いnamespaceからというのは嘘でした ×https://ideone.com/LpC58v 正しくは、解決不可能だった場合は、同じ階層から選択されるみたい。 AとBがともにNS2に存在する場合 https://ideone.com/m5leMs コンパイルエラー。 AがNS2 Bがひとつ外側のNS https://ideone.com/9IY4BC 同階層にBがない場合、グローバルからも選択されることはない。 https://ideone.com/cMhwpW >>604 ある。 単に人間に見えているタグ名が同じというだけで、コンパイラ内部では、 全く別の識別番号(というより、通常、コンパイラ内部の構造体定義データの先頭アドレス) になっており、タグ名が同じでも識別番号が異なれば、全く別物と扱われる場合がある。 >>603 ものすごい微妙な動きをするみたいだ・・・。 struct Base の定義を見てみると、外側に既に struct Data が定義されていても、 なぜか、Data は、「nested Data」すなわち、Baseの内部クラスの方を「参照」して しまうらしい。規則性はどこにあるんだろう。まだ英文読んでないけど。 struct Node { struct Node* Next; // OK: Refers to Node at global scope struct Data* Data; // OK: Declares type Data // at global scope and member Data }; struct Data { struct Node* Node; // OK: Refers to Node at global scope friend struct ::Glob; // error: Glob is not declared, cannot introduce a qualified type ([dcl.type.elab]) friend struct Glob; // OK: Refers to (as yet) undeclared Glob at global scope. /* ... */ }; struct Base { struct Data; // OK: Declares nested Data struct ::Data* thatData; // OK: Refers to ::Data struct Base::Data* thisData; // OK: Refers to nested Data friend class ::Data; // OK: global Data is a friend friend class Data; // OK: nested Data is a friend struct Data { /* ... */ }; // Defines nested Data }; 【違いの分析】 1. 外部クラスを参照したい場合の書き方: struct Data { struct Node* Node; // OK: Refers to Node at global scope ・・・ }; 2. 内部クラスを参照したい場合の書き方: struct Base { struct Data; // OK: Declares nested Data ・・・ }; 【考察】 後者の方は、「『宣言子』を「何にも書かずに」、ただ不完全定義として、 「struct Data」と書いている。こういう独特の特徴的な書き方で、 新しいタグ名の導入と見なされているのではないか。 一方、前者の方は、 「struct Node」だけではなく、「*Node」という「宣言子」を 書いてしまっているので、新しいタグ名の導入とは見なされない気がする。 先日書いた、CRITICAL なんたらの例では、宣言氏を書いていたので、「1」 の方の扱いとなり、外部クラスの参照と見なされた・・・。 >>609 D&E の 6.3.1 にそのあたりの解説があるので読んでみると面白いかも。 「病的な例」を含めてわかりやすい解決ルールを作ろうと奮闘したあげくに まあまあマシなルールとしてそうなったって感じ。 >>611 結局、>>610 のような結論であってるのかな? ぜんぜん違う ポインタだからサイズが決定できることになる ポインタなら前方宣言で前方参照できる 2. のほうは構造体を宣言してるから、そこに新しく nested class が作られてる。 1. のほうは構造体へのポインタを宣言してるから、対応する構造体を探して外部の定義を見つけてる。 そんなに微妙でもないと思う。 そもそもポインタでない場合、前方宣言でなくクラス(もしくは構造体)の宣言がないと インスタンスのサイズが決定できないし コンスタラクトタも呼び出せない 普通にコンパイルエラーになる クラス(もしくは構造体)のメンバにアクセスする場合も同じく 前方宣言でなくクラス(もしくは構造体)の宣言がないと メンバがわからない 普通にコンパイルエラーになる ポインタもしくは&の参照だけなら 前方参照だけで問題はない マジで頭悪いシロウトしかいない おじいちゃん今はタグ名前空間の話でしょ 不完全型のポインタが完全型になる話なんか今更ドヤ顔でしても恥ずかしいだけだよ また低学歴知恵遅れが的外れなこといってるし 低学歴知恵遅れってなんでこんな頭悪いん 頭悪いくせに頭悪いレスをする まず低学歴知恵遅れはC/C++言語の特性すらわかってない >>614 C/C++ では、ある1つの宣言で、ポインタ変数を定義する場合でも、それと同時に構造体の 宣言(定義)が行われる事がある。たとえば、 TYPE *ptr; は、ポインタ変数の ptr を定義しているが、TYPE の部分が struct TPerson { ・・・ } だった場合は、変数 ptr の定義と同時に、構造体 TPerson も定義する。 さらに、TYPE の部分が、 struct TPerson であった場合も、不完全定義として構造体 TPerson を定義することがある。 実際、先に挙げた例では、1つの行で、全く始めて _RTL_CRITICAL_SECTION 構造体が 出てきて、その不完全定義と同時にその構造体へのポインタ型のメンバ変数を宣言 していた。 型が struct TPerson みたいに書かれてて、 TPerson の宣言が見つからない場合、そこで TPerson が前方宣言されたものとして扱われる。 この前方宣言は一番内側の namespace かブロックに所属する扱いになる。 要するに一部の前方宣言は省略できるってだけだよ。 >>610 における2の書き方が新しいタグ名の導入と見なされる、というのが特殊ルールなだけで あとは>>613 でおk オール無問題 >>622 >>610 における2の書き方を前方宣言と解釈するなら、 構造体定義の中で前方宣言可能なブツが他にはfriendぐらいしか無い件について: (externは書けない、staticは別の意味になる しかもfriendは直後に完全型かポインタか参照を要求するですしおすし、 struct Data;という構文の際立ったユニークさは明らかすぐる… ていうかstruct Data;という構文には構造体の定義ブロックの外に書いたとき発動する存在意義が別にあるが そちらは前方宣言と言って良いかも試練、 こういうやつ↓↓↓ struct Data; struct Foo { struct Data* m_pData; // struct Fooはstruct Dataへのリンクを有する /*....*/ }; struct Data { struct Foo* m_pFoo; // Dataはstruct Fooへのリンクを有する /*...*/ }; そもそもなんで型の名前やクラス名だけではなくて、タグ名なんてものが存在し続けているのかというと、 struct Data;というのがやりたかったから、およびその必要が(上のようなケースで)あったからに他ならない >>624 struct Data* ptr;の記法が特殊なだけで、 struct Data;は一貫して前方宣言なのでは? >>627 >struct Data* ptr;の記法が特殊なだけで、 (不完全型)* ptr; とされてもコンパイラはptrへの代入や関数に引数渡しするコードを問題なく吐けるから int val; というのと大して変わらない話 コンパイラにとってはスゲー普通の日常業務 >struct Data;は一貫して前方宣言なのでは? 前方宣言というには>>610 における2の書き方で新しいタグ名の導入と見なされるという挙動がビョーキ もはやそれは内部クラスの定義にほぼ等しい(不完全な定義というだけ struct Data* ptr;の記法が特殊な根拠 struct A { struct Data* ptr; // as ::Data struct Data* ptr;の記法が特殊な根拠 struct A { struct Data* ptr; // ::Data }; struct A { struct Data; struct Data* ptr; // A::Data }; 前方宣言のあるなしで、解釈の変わるstruct Data* ptr;の記法はやっぱり特殊なんだと思うけど。 C++において、不完全な型という概念はあるけど、不完全な定義という概念はないのでは? struct A { struct Data* ptr; }; と記述した場合、そこからたどれる名前空間のどの階層であっても 事前に宣言または定義が行われていれば、その時点で特定可能なstruct Dataへのポインタと解釈されるけど、 解決不可能であった場合には、struct Aと同階層にあるstruct Dataとみなされる <- この動作が特殊 struct Bar;が前方宣言では「ない」という主張は撤回する なぜなら、次のコードの(A)、(B)のコメントアウトを外しても それ自体はエラーにならない(つまりstruct Bar; は同一スコープ内で重複が許される このときは(D)でエラーになる しかし、(A)と(B)をコメントアウトすると何のエラーにもならない むしろstruct Bar* m_pBar; の方が普通に前方宣言的に働く(Fooのスコープに縛られない #include <stdio.h> struct Foo { //struct Bar; // (A) //struct Bar; // (B) struct Bar* m_pBar; // (C) }; struct Bar { int x; int y; }; struct Bar* g_ptr; int main() { Foo test; test.m_pBar = g_ptr; // (D) } ちょっち訂正 △: struct Bar;が前方宣言では「ない」という主張 ○: 構造体の定義ブロック内のstruct Bar;が前方宣言では「ない」という主張 で、struct Bar* m_pBar; の方が普通に前方宣言的に働く(スコープローカルな新たなタグBarを作ったりしない)のに --(1) 構造体の定義ブロック内のstruct Bar;は明らかにスコープローカルな新たなタグBarを作り出すという変態機能を有している --(2) つまり(2)を指して一貫して前方宣言だと主張するなら、(1)のstruct Bar* m_pBar;も前方宣言の一種だと言わねば不正直である >>634 構造体の定義ブロック内のint i;は明らかにスコープローカルな新たな変数iを作り出すんだけど、 それも変態機能だと思うの? (1) が前方宣言的に働く理由は >>622 で説明したんだけど、通じなかったかな… >>634 >struct Bar;は明らかにスコープローカルな新たなタグBarを作り出す 構造体定義ブロック内に限らずとも、前本宣言はもともとすべてスコープローカルだけど。 それはグローバルであっても、中間階層の名前空間であっても、 多重ネストの構造体の中間階層で会っても同じ。 拘ってる人は自前でコンパイラでも作ろうとしてるのか? >>615 ポインタでない場合というと struct aho; struct boke { aho begin(); aho end(); }; こういうのもあるな 最初に質問を書いた者だが、この話は、実は仕様が決まっていて、 記憶だと、手元にある ARM(Annotated Reference Manual) にも、確か 何か書いてあった。 見るのがメンドクサくてここに質問を書いたんだ。スマン。 レスdクス、 >>636 なるほどスゲーよくわかりた >>635 構造体の定義ブロック内のint i;は2回同じものを書いたらエラーになるから宣言ではなくて定義じゃわパオーン 構造体の定義ブロック内のint i;は2回同じものを書いたらエラーになるから宣言ではなくて定義じゃわパオーン その他の方々もだいたいおk プログラム間でデータ共有する方法はメモリ共有とファイル経由以外に何がありますか >>643 ・WM_COPYDATA メッセージで送り合う。 >>643 Windows ならメールスロットとパイプもアリかな。 質問者の意図がようわからんが データ本体(スゲー巨大かもしれない)の共有にいちいち通信時間を要する手段は除外されるんじゃ… やっぱプロセス間の同期をミューテックスか何かのプロセス間でも使える同期オブジェクトまたはソケット通信とかでとる前提で、 データ本体のはメモリ共有かファイルという手段になるのではなかろうかと、 ファイル渡しの方が通信よりよっぽど時間がかかると思うが。 >>649 共有のニーズが生じてからファイルを作るのならそうだが 最初から共有データとしてファイルが存在する場合はそうではない というわけで質問者の意図にはようわからん点がある ディスクアクセスの遅さ考えたらわかるだろ、ふつう。 >>652 想像力が欠如すぐる… 共有しようとするデータのサイズが1 TBなら、全部送ろうとしたら3GB/sの転送速度でも333秒かかる ファイルを1個置いといてfseek()する方がまだまし たった一行の素朴な質問からどこまで膨らませられるかコンテスト開始 通信推しの人としてはそう言いたくなる気持ちもワカル 1TBのデータ共有するのにファイルからは1TB読まなくてもいいという謎比較。 同一の計算機で何度も読むことが分かってるのに 別の計算機でディスクアクセスさせて それを通信でやりとするアホなシステム構成にするヤツがあとを絶たないのがよくわかる 著しい低学歴知恵遅れがそういうことよくやる 世の中には常識をこえるすごい頭悪いヤツラがいるからな 何度も何度も計算機Aから計算機Bの数十ギガを超える共有ファイルの内容を計算機Aにすべて読み込んで 計算機Aで処理をなん百回も繰り返す しかも共有に使うSamba つまりNBT() Windows共有とまったく同じ つまり毎回毎回計算機Bにディスクアクセスして通信(NBT経由)使って 計算機Aで読込むということを意味する それで遅い遅いなんでといってたからな。。。 世の中には想像を超えるこんな頭悪いのが現実にいる >>656 むしろ毎回データ全部を丸ごと送る想定なら、高速な通信手段で良くて 「データ共有する」(>>643 )という質問者の動機にならない件について: メモリ共有であれば通信より高速を目指す目的で毎回データ全部を丸ごと送る風に使われることもあるが 質問者>>643 は共有手段として「ファイル」も挙げているから いきなりそこまで話を限定できないワケ んまー今思いついたがメモリ共有やファイルの他には データベースみたいなデータを出し入れ管理するプロセスなりサーバなりを設けるというのも >>643 の答えに含まれるのかもしれん… >>656 の思い込みとはうらはらに、 データベースXにアクセスするプロセスA、Bは、明らかにXが管理するデータを共有しているが、 Xの管理するデータ丸ごとを毎回送りつけ合うわけではないし、 なんか長々と書いているようだが、全部送ろうが一部だろうが正しく同条件で比較すれば一目瞭然だろう。 1. プロセスAが巨大なファイル中の一部のデータの読み込みをファイルシステムに要求する 2. ストレージから読みだされたデータが返される 1. プロセスAがプロセスBが持つ巨大なデータ中の一部のデータをRPCで要求する 2. プロセスBからデータが返される >>660 データベースなら例えばSQLでやりとりやね 既にオンメモリで数ギガ扱うのに対応してるしプログラム間通信も高速 なにより統一されたプロトコルでオンメモリからネットにまでアクセスできるのが便利 >データベースみたいなデータを出し入れ管理するプロセスなりサーバなりを設けるというのも これを実現する手段として>>644-646 のような手段があるわけだが、それ認識してなかったのか。 それはデータベースとは言わんのじゃ? COPY_DATAやメールスロットはOS提供の簡易的なプロセス間通信サービス RPCはデータ以に上さらに高度にアクセスするプロシージャ データをどう持つかというのはこの際どうでもよくて、>>663 はそのサーバープロセスと データをやり取りする手段の話ね。 >>663 >これを実現する手段として>>644-646 のような手段があるわけだが、それ認識してなかったのか。 >>644-646 はデータを送りつけるという通信の手段のみ述べており、データ共有の実現に行き着いていない もちろん通信だけでもプロセスAとBの間で情報の共有はできるが、 >>644-646 の言説だけでは、情報を表す入れ物である「データ」の共有に行き着いていないワケ >>644-646 の言説が含意するのは、同じ情報iを、プロセスAがデータa、プロセスBがデータbとして持っている状況、 というところ止まりで、aとbは別物。さらにいうと、同じ形式のデータであることすら導くことができない この差異は形而上の問題ではなく、現実の設計の問題である >>644-646 だけでは、AがBに情報伝達するにあたりBに通信する(通信のエンドポイントとしてBを起こす)必要があるから Bが風邪で休んだりするとAの仕事まで止まってしまうことが確定する 一方、AがExcelシートXに情報を書き、Bが必要なときXの情報を参照する、という方式だと(他に付帯条件が無ければ)Aは問題なく仕事を続けられる データ共有というのは後者 今度は「共有」という言葉の定義論か。それを>>647 で言っていたんならそう問題はなかったろうがな。 どっちにしても通信時間が云々というのが的外れなのは変わらない。 見苦しい。 なぜ機能とそれを実現する手段を混同して語るかなぁ… Excelのブック共有だってExcelアプリケーションがファイル共有とか使って頑張ってるから実現できてるんだし そもそも>>643 は手段レベルの話だし >>667 と>>668 は通信でおk、と叫びつつ、ネットワークのトポロジーの差異を認識しないおマヌケちゃん 結局通信についてもデータ共有についても素人なのでした 残念ながらリアル郵便網を使うプロトコルスタックはないので伝書鳩にした方がいい 伝書鳩はパケットロスの可能性が高いので冗長化が必要 ループバックができる鳩は往復鳩といって 普通の伝書鳩より訓練が難しいんだぞ 手段の話であれば極論口頭でもいいわけたが、勿論そんなこと聞きたい訳でもなし >>643 実は、GDI の Device Context の HDC も、プロセスの垣根を越えて渡す方法がある、 メモリコピーは伴わずに。やり方は、PrintWindow(HWND hWnd, HDC hDC, DWORD flag) API を使って、WM_PRINT メッセージを送るというもの。これを使えば、グラフィックデータ ならBITMAPデータも伝達できる。たとえば、HDC を用いて GDI+ の LockBits() を 使うと良い。L。 https://mevius.5ch.net/test/read.cgi/tech/1474384848/338 C++を使ってる仕事につきたいのですが、どこもC++を使ってるところは組み込み系とかの経験の募集ばっかです 私はwebしかやったことないので組み込み系の経験はありません >>679 ここはダーマの神殿ではない、と言いたいとこだけど、年齢によるね。 未経験でも30歳前後なら余裕、35歳超えなら諦めろ。 というか組み込み系でC++を使っている分野ってあるにはあるけどそんなに多くはないよ。 組み込みLinuxでのアプリ開発ぐらいなんじゃない? 老害から言わせてもらうとアレは組み込みソフトじゃないけど。 >>680 25です Linuxでのアプリ開発分野ならあるんですね‥ 別に組み込みじゃなくてもいいんですけど、探したら組み込みがほとんどって感じです 本気で探しているのですが、難しいです‥ 頑張って探してみます 25歳なら第二新卒扱いで組み込み未経験でも全然OKよ。 募集要項に経験者って書かれてても怖がらずどんどん応募してみては? 相変わらずこの業界は人手(奴隷)不足なのでそう苦労せず転職できると思う。 売り手市場の今は転職先の会社を見極めて選り好みすることができるので、下手に妥協せず納得行くまで転職活動頑張って! >>682 ありがとうございます! 目標に向かって頑張ります 相談に乗ってもらってありがとうございます 相談してよかったです! 普通にC++でWindowsようのデスクトップアプリ作ってるけどなあ それように人員を募集してるかっていうとしてないけど >>684 普通に羨ましいです‥ 自分は中々見つからないです >>680 組込でガッツリは使ってないけどBetter CとしてC++使ってる所はそれなりにあるよ ちっこく作って別プロセス立てするってやり方はあるけど それ以外だと大規模なゲーム開発くらいしかあんまり聞かないな。 なんでc++の仕事したいんだ? 言語縛りにする意味がわからんな C++の最新仕様に詳しくてもあんまり仕事で使えないからな メタプログラミング駆使して行数少なく書いてもぶっちゃけ大した価値ない 逆にやりすぎて嫌われるのがオチ CPU、キャッシュ、バスアーキ、OS、ABI、Toolchain、各種デバッグ手法などを知ってる方が重要 言語仕様詳しい癖にmake書けない奴とかいるからな VisualStudioばっか使ってるからmakeかけないわ・・・ makeは依存ファイルと生成ルールをひたすら書くだけだからな あんなしょうもないのを書けないほうがおかしい makeは暗黙ルールとか特殊変数とか予約ターゲットとかアーカイブの特別扱いとか 罠や地雷や落とし穴が満載で人間が書くもんじゃない 昔はmake書けないやつ馬鹿にしてたが、ひざに矢を受けてしまってな…… 今いるのやや学術よりのとこなんだけど、回りがPythonばかりになってきて690の気持ちが分かってしまう linuxのmakefileをwindowsで使おうとしてハマってぶん投げたのはナイショ makeは泥沼、mkmfやら数多のツールすら呑み込む底無し沼・・ makeを書くだけなら簡単だがクロスプラットフォームで更にいくつもオプションが増えてくると人力で書くこと自体が間違いでしかなくなる 環境導入楽なGUIアプリケーション作成用ライブラリないかなぁ QtはQtCreatorが使いづらくて ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.0 2024/04/24 Walang Kapalit ★ | Donguri System Team 5ちゃんねる