C++相談室 part134
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。 !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part133 http://mevius.5ch.net/test/read.cgi/tech/1511509970/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 http://mevius.5ch.net/test/read.cgi/tech/1509780815/ ■長いソースを貼るときはここへ。■ 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から来た連中ってどうしてmemcpyやmemset使いたがるんだろうな >>76 reinterpret_cast でなければ通らないときはだいたい駄目なときやわ。 >>100 「default がバイト列コピーとは『限らない』」という意味で >>84 は真。 開始アドレス、終了アドレス、サイズが64bit等で割り切れれば バイトコピーより早いコピーはあるだろうね 頭のいいコンパイラなら勝手にベクトル処理とかしてくれるんじゃないの? 知らんけど "!"!"!MOHYO!"!"!"2" 1.[[[HUn≒MUL=POSI≠MAHO+Set*HUGE=SAGE=LOGE=NOISIA=0≒1]]] 2-[[[[[[[E=RAT%2^10%SPELAn!%]&!TOWA&!PEG#!NOLNOL8!#!HYAGO!2#]1*2=1]U]S]0]O]!#PAL! 3--->PAGODOL7&!@17,2222734.15&[[[%%RENRAK6,9,99"^10"]#$11.2%}]KAIJ]{ 41.2SSS = RALQI2.β{{{RA4,0,238^97,1,$.S.L.E.I.L."Q5352.15Q"JOL"5*3>>>41 .3q}}}>1.2<0 .3φTALHOSI"0">>>105 .10<1.235<1.2>51≠52===55.632>V="E=0.835"of"1.32","632",0.683,1.end { C++では、 int i; for (i = 0; i < 9; ++i) { ... } が、 for (int i = 0; i < 9; ++i) { ... } って書けるのは知っているだろう。( )の中で、変数を宣言できる。 だが、ifやwhileの( )の中で、変数を宣言できることを知らない人は多い。 C++17では if ( auto v = n; conditions ) { ... } が可能になるし、これからは広がってくれるかのう for( ) の制御変数はそのループでしか使わないことが多いから意味あったけど、if( ) でそんなケースはまれだしなぁ あれば使うけど待ち遠しいって言うほどじゃない気がする 理想主義的な文法ですが、実効性はあるのか疑問ですね 一瞬意図が分からなかったが ()の中が;で区切れるという話? dynamic_castとの組み合わせで使うとかどうよ 結構あると思うけどね if(DWORD err = GetLastError(); err != NO_ERROR) この場合NO_ERRORが0だって分かってるから if(DWORD err = GetLastError()) で済むから無意味だけど >>116 前者の方が意図が明確だし意味はあると思う >>116 >if(DWORD err = GetLastError(); err != NO_ERROR) 普通こうやろ if((DWORD err = GetLastError()) != NO_ERROR) 変数宣言は少しは意味あるかもしれんが(Perlと同じことができるってこと) 複文書けるのは特にメリット感じないわ それ通らんよ こうだろ DWORD err; if((err = GetLastError()) != NO_ERROR) if内でしか使わないerrが外部に漏れてるのがよろしくないってこと >>119 それが通るという変更だと思ってたわ こう書けるPerlのほうがまだ優位性あるね if((my $err = GetLastError()) != NO_ERROR) if(init ; expr)だと初期化と式が関連していなくてもいいので>>120 とは違う構文になる だからこんなのでもよい if(int err = GetLastError(); hoge.aho()) lock_guardもしておける if(std::lock_guard<std::mutex> lock(m); flag) 構造化束縛も使える if(auto [a, b, c] = f(); b > c){ std::cout << "b > c" << std::endl; } Cでは名前空間っていうのをすごい扱っていた気がするんだけどC++は名前空間扱うことってないの? 一つのアプリケーションも完成させたことがないど素人の質問ですまんが >>122 まずは"C"の入門書を読んで、何を見間違えたのかはっきりさせてからにしようか。 構造体タグと型名の名前空間が分かれているといったような意味での名前空間は C に有るが C++ では構造体タグはそのまま型名としても使えるし、そういう意味での名前空間の話かな? こんな名前空間もあるね int x; int main(void) { x = 1; int x; x = 2; { int x; x = 3; } return 0; } 謎すぎワロタがそこから上のスコープのxを参照してくれ std::mapのように文字列や構造体をキーにした高速アクセスができて、 要素の数が一定数を超えたらLRU形式で勝手に削除してくれる、 キャッシュのような機能を実装したいのだけど、 C++でそのような仕組みを作れるクラスはないですか? 自分で実装するならどうにでもなるだろ そのための道具は全て標準で揃っている バックグラウンドならスレッド使うしかないんじゃないかな C++のプログラマーって性格ねじ曲がってるなあ 初めてGo応援したくなったわ >>137 どんな点が、性格悪い、と思わせるのですか? >>136 要素数が閾値を超えるのは要素が追加される時だからその時に古い奴を削除すりゃいいだけじゃね? >>135 簡単で良いのでサンプルコード書いてもらえませんか? >>135 じゃないけどシンプルにいくなら { map<key,value> data; // 本来のデータ map<key,list<key>::iterator> lruindex; // list<key> lrulist; // LRUリスト ... // mapと同じインターフェイス } みたいなクラスで要素の追加・削除・参照とかの時にLRUリスト見て処理すればいい 辞書・線形リスト・2分木を、組み合わせる。Ruby で書くと、 class LRU_hash def initialize (max_size = 3) # ary は、hash に追加・アクセスした順 @hash = {}; @ary = [] @max_size = max_size end def push (key) if @hash.has_key? key # 一旦、要素を削除してから、最後尾に追加しなおす @ary.delete key else if @max_size == @hash.size # 先頭要素を削除してから、最後尾に追加する @hash.delete(@ary.shift) end @hash[key] = true end @ary.push key end def print_buf puts @ary.join ', ' end end ary = ["あ", "a", "あ", "い", "b", "あ", "c"] hash = LRU_hash.new 4 ary.map { |key| hash.push key } hash.print_buf #=> い, b, あ, c >>144 > # ary は、hash に追加・アクセスした順 参照のたびに最後尾に追加しなおすの? プログラムを作っていて困っています。 プログラム動作環境、windows 7 x86_x64 プロセスをExplorerを親として、 起動したプロセスにファイルの存在するディレクトリを作業ディレクトリとして 割り当てたい。 ただし、プロセスへのアタッチによる変更は禁止とする。 ようするにファイルをダブルクリックして起動するのと同じ状況を再現したいのです。 例 C:\hoge\fuga.exe [現状] Explorer C:\hoge\fuga.exe 親 explorer.exe カレントディレクトリ C:\Windows\System32\ [理想] Explorer C:\hoge\fuga.exe 親 explorer.exe カレントディレクトリ C:\hoge\ >>145 >>134 で、LRU と書いてあるから、Hash に追加しようとした度に、 すでに存在する場合でも、配列の最後尾に追加しなおした どういう意味か、正確にはわからないけど >>146 explorer.exeへのショートカットを作ってプロパティで作業ディレクトリを指定するか、 COMでIShellLink::SetWorkingDirectoryを使って同じことをするあたりか? みなさんありがとうございます。 std::mapにLRUや最大要素数の仕組みを持たせた派生クラスでも 無いかと思ったのですが、標準ではやっぱり無いですか。 >>143 のように、std::mapをメンバの一つに持たせた独自クラスを 一から作っていくことになるんですかね。 amazonランキングの謎を解く とか言う本でmove-to-frontを見た 本の紹介「Amazonランキングの謎を解く」 http://www.kenkyuu.net/whatsnew/2011/08/book2011-08-01.html >「move-to-front規則」(最後に売れた順に並べる、つまり、注文のたびに1位にジャンプする) Move To Front - Wikipedia https://ja.wikipedia.org/wiki/Move_To_Front >>149 「c++ lru map」でググったか? いくつかサンプルになりそうなコードが見つかるんだけど C++を勉強しようと思ってる者ですが書籍を探しております。Cはある程度書けるのでそれを前提とした書籍が欲しいです C++ クイック入門&リファレンス プログラミング言語C++ 第4版 >>155 C++11 以前だが accelerated c++, ここでフォローするよ 以下のようにconst char*型の文字列でchar*型の変数を初期化したいときに strcpyやstrlenを書かずにstd::stringを利用して短くかけないかと思うのですが msvcだとエラーにならず、clang, gccだとdeleteでセグメンテーション違反になります。 どうすればより良い感じになるでしょうか?const_castはできれば使いたくないです。 #include <string.h> #include <string> #include <iostream> int main() { const char* asdf = "asdf"; // char* psz2 = new char[strlen(asdf)+1]; // strcpy(psz2, asdf); std::string *psz = new std::string(asdf); char* psz2 = &(*psz)[0]; std::cout << psz2 << std::endl; delete psz2; return 0; } delete psz2なんてしちゃだめconst関係ない 何故stringそのものじゃなくて内部データをdeleteしようと思ったのか newで確保した配列じゃないからdeleteはできない stringの内部データは静的な配列と動的な配列を組み合わせて表現されている mscvの場合先頭16文字はchar[16]でそれ以降は動的な配列に入るようになっている psz[0]のアドレスはchar[16]の先頭アドレスなので当然deleteできない msvcはdeleteに失敗しても落ちないのかな >>155-159 本格的な本なら、ロベール、ハーバート・シルトの独習 軽めの本なら、柴田 望洋、林 晴比古、猫 ハンガリー人まだ絶滅してないのか。 stringはnull terminatedでないからpszはおかしい。 psz2もnull terminatedの保証がないからc_strを使うべき。 うまくいったらstrdupも調べとこうな。 >>162 char* psz2 = &(*psz)[0]; って char* psz2 = psz->c_str(); と同じなのかな? いずれにせよ delete psz; は出来る(するべき?)だけど、 delete psz2; は出来ないんじゃないかな。 必要ないところでnew/delete使う人は根本からして何も分かってない >>162 お前はstringがただの配列だと思っているのか? このトンチキ野郎! >>162 弁護士の唐沢です しっかり「char* const」と「const char*」の違いを認識しなさい const char*は参照先の定数を変更しない事を保証する宣言であり、char*は参照先の定数を変更できる為、const char*で保持するアドレスをchar*にコピーする事は言語仕様により禁止されています。それは分かるよね? 最初に宣言したポインタを間違えて別アドレスで上書きしないようにconstで固定したいのなら、char* constを使うようにしましょう。とりあえずとりいそぎ >>162 strdupという手があるが何がしたいのか今一つ分からない const char* asdf = "asdf"; char *p = strdup(asdf); std::cout << p << std::endl; delete p; >>167 データは連続しているので同じになる 16文字まではスタックを使い、それ以上の長さになるとヒープにコピーされる 実装ではメンバの配列には何かしらのエスケープ文字が入る ちなみにmsvcでは実装の都合上free(&str[0])で強引に解放できる 補足 スタックとヒープを使い分けるかどうかは実装依存 gcc、clang、msvcでは行われている したがって短い文字列でnewを避けるためにstringを使わないというのは意味が無い >>171 strdupで確保した領域をfreeでなくdeleteするのは正しいの? >>175 弁護士の唐沢です mallocとdeleteは併用厳禁です。freeを使用してください >>176 良くねえだろ ぼけ >>179 開放はpublic的なニュアンスだよな >>162 ぶっちゃけた話、 strcpy が一番短いと思う。 >>182 strdup という答えが出てるのに何言ってるの? >>183 strdup は C++ の仕様の範囲内ではないので……。 POSIX と MSVCRT に有るからほとんどの場合に十分といえば十分なのかもしんないけど。 >>166 接頭辞を見ればデータ内容の属性がワカルというメリットは他に代え難い ttp://local.joelonsoftware.com/wiki/間違ったコードは間違って見えるようにする あといちいちthis->xと書くよりも、すすんでm_xと書きましょう strdup()だと明示的に開放コードをどっかに書かなくてはならなくて必ず忘れるので せっかくC++なのでスマポ的にwrapすると良いと思う ホワイトボックスなCでは許せるが ブラックボックスなC++の流儀には全く合わない それがstrdup >>173-174 教えてくれてありがとう。 返されるアドレスは等しい値なのか、という単純な質問だったんだけど、 読み直してみたら分かりにくい質問文だと思っていた次第。 それにしても &(*psz)[0] って結構ややこしいのね。 オーバーロードされた[]演算子が返すcharへの参照、 に対してアドレス演算子&を作用させた結果、て感じかな。 すみません、たくさんレスありがとうございます。 _strdupにしてみたら期待の動作ができました。 ありがとうございました。 また質問してすみません。 msvc(vs2017)だとコンパイラをC++17にしても以下のプログラムで C2664 'void (T *&)': 引数 1 を 'hoge *' から 'hoge *&' へ変換できません。 となってしまうのですが、コードにバグが有るでしょうか?msvcのバグでしょうか? GCCやClangではコンパイルできます。 #include <memory> struct hoge {}; template <class T> inline void safe_delete(T*& p) { if (p) { delete p; p = nullptr; } } int main() { std::unique_ptr<hoge, decltype(&safe_delete<hoge>)> sp{new hoge(), safe_delete<hoge>}; return 0; } (T *&) そもそも、ポインタ・参照を、同時に使えるのか? new hoge()は変数じゃないから、代入できない。 >>165 独習C++ はいいですね、特に演習問題「std::stringを再実装する」を絶賛します これが書けるようになったらC++初級者をかたってもいいかもしれない、もしかすると解答は載ってなかったかもしれないけれども >>185 どこから引用したのか知らんけど、そのページ読んでないだろ… システムハンガリアンはまるで役に立たないって書いてあるぞ。 >>194 (システム)ハンガリアンってそんなに悪いものなんですかねえ いや、win32api がバンバンハンガリアンしているので、そんなもんか、と思っていましたが >>195 OOPともTMPとも型推論とも相性が悪いからね。 MS自身ももう使うなって言ってる。 嫌いだからハンガリアン意地でも使わなかった dwやらszやらせっかくのフリーフォーマッとが台なしだよ ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる