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 代入演算子に左辺値参照修飾しとくと、右辺値に代入できなくなったりする 他はなんかあるかな・・・ C++11で追加だったのね。ありがとうこざいます。 https://kagasu.hatenablog.com/entry/2017/05/02/120156 このページで、例えば ifs.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffff, consume_header>)); というのがあって、locale()の第二引数でnewされたものがありますが、 これをdeleteする記述が見当たりません。 他のページでも同様です。 リークしてそうで怖いのですが、一体どこでdeleteされてるんでしょうか?? >>546 参照カウント方式で管理されてて、デストラクタでdeleteされます >>547 素晴らしい! RAIIですね。 安心しました。 ありがとうございました! 普通にどうプログラムを書いていいのかわらないので 質問したいのですがよろしいですか? すれ違いならすいません 図1 000 000 000 図1の0の部分を0から9までのすべての数字に置き換えたものを 表示して変数に格納する 図では3X3にしましたがnXnだとしてください。 説明が下手かもしれませんがよろしくお願いします 0から9までのすべての数字は10個あるが 場所は9個しかないがどうするの 説明が下手ですいません 236 000 011 こんな感じで9か所すべてに0から9まで入ったものを全パターン格納したいです .csvにして出力したいので excelで手打ちするよりはいいのかなと たぶん、20GBほど必要だけどいいんか? 全パターンにこだわらず、乱数で必要な数だけ生成したほうが良いのでは? おっとinodeの最小サイズがあるから100倍くらいかしら それは3*3を1次元で考えると 0 0 0 0 0 0 0 0 0 から1ずつ増やして 9 9 9 9 9 9 9 9 9 まで表示して全パターンを変数に格納ってこと? 単純に1桁1バイトで考えると1パターンにつき9桁9バイト必要なので、格納領域だけで9000000000バイト=約8.4ギビバイト必要なんだけどそういうこと? 1000パターン/秒の速度で表示したとしても104日かかる計算になる。 課題か何か知らないけど、問題を勘違いしてるのでは? 3*3だったら要素数9の配列を用意してループで回せばいいだけじゃないの? 9!≒36万行のcsvが欲しいのか? 4x4だと16通りで16!=20?922?789?888?000 おおよそ21京行のcsvファイルが出来上がる 5x5だとwikipediaにもoeisにも載ってないが 15,5112,1004,3330,9859,8400,0000 らしいので 15.5穣行のcsvファイルが出来上がる Yが一歩手前の??なんで、世界中の記憶媒体を寄せ集めても足りるかどうか・・・ 6x6だと36!の 37,1993,3267,8990,1217,4679,9944,8150,8352,0000,0000 37正 csvファイルを作り終える前に人類滅亡するレヴェル 実際に必要なのは160万通りぐらいだけど無理? 無理なら諦めます 全ての場合分けを検討できないから、枝刈りしようよ。 全パターン網羅じゃなくてピックアップでいいなら乱数という手段もありでは 乗り遅れた… 鏡像とか回転の扱いをどうするかとか 楽しそうな課題だな N×N のテーブルを N 種類の値同士の演算結果と考えて その演算結果が群の性質を満たすパターンだけを取り出す というような課題はやったことがあるな。 群論的には値の個性は意味がなくて、 たとえば全ての 1 と全ての 2 を交換したようなパターンは 等しいという扱いになってしまうので、 それを除去するのが面倒だった。 いや、この話題の流れには関係ない話なんだけど >>571 を見て思い出したもんだから。 vector A に vector B を部分代入することってできないの? つまり、代入後は vector B が vector A の部分vectorになっててほしい 部分vectorって言ってるから、Bを参照扱いで挿入出来ないかってことじゃないの? Bを書き換えたらAにも反映されるみたいな。 まぁ、vectorじゃ構造上無理なんだけど。 >>572 >N×N のテーブルを N 種類の値同士の演算結果と考えてその演算結果が群の性質を満たすパターンだけを取り出す すごく興味がありますね… 準同型を検出するのが難しそうですが、ガウス吐き出し法で同一解(ただす解を小さいもの順に並べなおす)を弾くようにするだけでなんとかなりますか? ググッてみると、位数12 の群のひとつは、巡回群でも巡回群の直積でもない、これより低位には現れなかった新たなパターン、らしいのです、これはどんな群なのか具体的に知りたいものです 小さい群ならいいだろうけど、散在型単純群が出てくるサイズになっても対応できるかな using FUNC = std::function<void(Params&)>; struct Params {}; template<> std::tuple<> convert_params(const Params&) { return {}; } template<> std::tuple<int> convert_params(Params& p) { return 0; } template<typename... Args> inline static auto message_handler(void(*func)(Args...)) { return [=](Params& m) { std::apply(func, convert_params<std::tuple<Args...>>(p)); }; } template<typename... Args> inline static auto message_handler(std::function<void(Args...)> func) { return [=](Params& m) { std::apply(func, convert_params<std::tuple<Args...>>(p)); }; } template<typename T, typename... Args> inline static auto message_handler(void(T::*func)(Args...), T* obj) { assert(obj != nullptr); return [=](Params& m) { std::apply(func, std::tuple_cat( std::tuple<T&>(*obj), convert_params<std::tuple<Args...>>(p)) ); }; } ↑の続き 前の投稿で定義した関数を使い、下記の通りに呼び出そうとしているのですが std::functionを通さずにラムダ直で呼び出した場合に、なんとなく上手にやってくれる 方法がどうしても思いつけません。何か手はないでしょうか? 1 void myfunction(int); FUNC func = message_handler(myfunction); // OK グローバル関数 2 void myclass::myfunction(int); FUNC func = message_handler(myfunction, this); // OK メンバ関数 3 FUNC func = message_handler([](int){}); // NG ラムダ直 4 std::function<void(int)> myfunction = [](int){}; FUNC func = message_handler(myfunction); // OK std::function 頭に+つけると上手くいくと思う FUNC func = message_handler(+[](int){}); >>585 あれ、マジでうまくいきました。 調べ方がいまいちわからないのですが、これはどういった機能でしょうか? すみません、お礼を言い忘れています。 ありがとうございます。 >>586 std::decayと同じ働きをするようなもので、ラムダ式を同等の関数ポインタへ変換する(ただしキャプチャをしてはいけない) なんて調べればいいのかはよくわからない・・・ 突然すまんが、 winnt.h の中に次のような構造体定義があって、外部では、構造体タグ名 _RTL_CRITICAL_SECTION が不完全定義すらもされないで、 _RTL_CRITICAL_SECTION_DEBUG の中でポインタのために使用されている。 仮にこれで、「内部クラス」扱いにならないのだとすれば、 逆に、「内部クラス」を使いたい場合、もし完全定義を与える前に、 不完全なままポインタのために使いたい場合は、どうしたらいいのだろう? typedef struct _RTL_CRITICAL_SECTION_DEBUG { WORD Type; WORD CreatorBackTraceIndex; struct _RTL_CRITICAL_SECTION *CriticalSection; LIST_ENTRY ProcessLocksList; DWORD EntryCount; DWORD ContentionCount; DWORD Spare[2]; } RTL_CRITICAL_SECTION_DEBUG,*PRTL_CRITICAL_SECTION_DEBUG; typedef struct _RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUG DebugInfo; LONG LockCount; LONG RecursionCount; HANDLE OwningThread; HANDLE LockSemaphore; DWORD Reserved; } RTL_CRITICAL_SECTION,*PRTL_CRITICAL_SECTION; 確か、構造体タグ名は、ブロックに名前空間があって、C と C++ で仕様がごちゃごちゃしていた 気がした。 確か、既に定義がある場合は、それが定義された段階の名前空間を使うが、 完全に新規に定義する場合は、最も内側のブロックの名前空間に登録される、という 感じだった気がしたんだけど。 一度も外部では定義も宣言もしなかった場合、最も内側のブロックの名前空間に登録されるの だとすれば、クラスや構造体内部の内部クラスに関してもそれの応用になって・・・、と思うんだが、 少なくとも、旧来の C のヘッダファイルでは、その解釈ではまずいことになっている気がする。 struct _RTL_CRITICAL_SECTION; って行があるんじゃね 不完全な型はそれを解決する必要があるときに完全な定義が得られればいいんで、 それがどこの名前空間に存在するかについてもそのときに解決できればよかったはず。 >>591 無い気がする。 さっき思ったんだけど、C++ の場合、winnt.h の大部分は、extern "C" {・・・} で囲まれて パースされて、旧来の C の仕様のままになるので、内部クラスの概念が無いから あれでいいのかも知れない??? >>592 _XXX_DEBUG の方で、_RTL_CRITICAL_SECTION を _XXX_DEBUG の構造体に所属する 「内部クラス」 に解釈してしまった場合、外側の _RTL_CRITICAL_SECTION では、 タグ名としては同じ名前であっても、コンパイラにとっては全くの別の構造体に見なされて しまうので、たとえば、ポインタを代入する際に、 「異なるポインタ型への代入がある」 などのエラーが出る可能性がある。 >>593 extern はリンケージを制御する仕組みで、 extern "C" にしても文法の解釈には影響を与えない。 C として解釈されたりはしないはず。 ? その「内部クラス」 の定義は存在しないんだから。 何のための不完全型かと 型の中身を意識する必要はない リンケージなんか関係ない >>597 不完全定義でも、厳密にどの構造体かは区別されている。 不完全型でいけそう https://ideone.com/SFcGAQ 内部クラスと解釈はされないみたい(内部クラスと解釈されたらリンクリストで困るような) https://ideone.com/DcYHNu 詳しい仕様は誰かプリーズ >>599 >(内部クラスと解釈されたらリンクリストで困るような) しかし、外部クラスと解釈される場合は、本当に内部クラスにしたい場合で、 それ自身が自己参照を持つリンクリストにしたいような場合に、逆に困る 事になるかも知れない。 struct Bの定義は内と外両方同時に存在し得て、検索順で近い方に解釈されるというだけだろ。 何を心配してるのか。 >>601 別の名前空間の構造体だと解釈されれば、ポインタの代入も出来ない。 >>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 プログラム間でデータ共有する方法はメモリ共有とファイル経由以外に何がありますか ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる