C++相談室 part136
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part135
https://mevius.5ch.net/test/read.cgi/tech/1522495206/
このスレもよろしくね。
【初心者歓迎】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 >>211
他に方法がないが、いちいち mark and sweep するなんて考えられない >>213
>循環に限らず単純な共有でもこうなるので
到達済みフラグをセットするのは開放時なので
ならない
>ドーナツ型の図形を塗りつぶすのと同じやり方(>>213)
と書いただけでは通じなかったですかそうですか、 ごめwwwwww
×:到達済みフラグをセットするのは開放時なので
○:到達済みフラグをセットするのは参照カウントを減らすときなで と思って今作ったがあんま使い勝手の良いものにはならんかったorz
使い方としては
class Foo {
sumapo<Foo> m_pCar;
sumapo<Foo> m_pCdr;
/*...*/
};
sumapo<Foo> ptr(new Foo());
と書いた後、ptrが開放されたとき、ptrが指すFooが握っているsumapoが残らず(循環があろうとなかろうと)参照カウントを減じて欲しいわけだが
これにはptrが握っているFooを開放する前に、ptrがFoo::m_pCdrやFoo::m_pCarを辿れる必要があるので
m_pCarやm_pCdrとptrが裏で手を握る必要がある ごめwwwwwwwまた言い方をちょっとまつがえたorz
誤: Fooが握っているsumapoが残らず(循環があろうとなかろうと)参照カウントを減じて欲しい
正: Fooが握っているsumapoが(循環があろうとなかろうと二重破棄を招かない形で)参照カウントを減じて欲しい
リフレクションがあればsumapoからFoo(やBar)のメンバが丸見えなのでsumapoのリンクを辿って破棄予定オブジェクトを事前にマークすることで2重破棄の防止を自然に実現できる
リフレクションが無い現行のC++なら、sumapoのデストラクタで破棄される予定なFoo(やBar)をマークだけして破棄を遅延する、みたいな細工をするしかないが
デストラクタの中から全てのFoo(やBar)のマークが完了したか知る術が無いから、sweepする呼び出しが別途要る、、
やっぱC++にもリフレクション欲しい… >>224
JavaScripterマジで死ねよ
JavaScriptのコミュニティが腐っているのは、
馬鹿であることを自覚出来ないお前みたいな大馬鹿が、嘘を平気で垂れ流しているからだよ。
そして初心者はそれを見抜けず、騙されて馬鹿が再生産されてる。
お前らがC++のコミュニティを破壊する権利はない。JavaScriptのゴミ貯めに戻れ。
お前らはプログラマ全体からするとゴミ以下のクズなんだよ。それを自覚しろ。
C++初心者の為に、俺がお前の嘘を暴いておいてやる。
> リフレクションがあれば
お前のリフレクションの使い方は、メンバの中身を参照したいだけのようだ。
ならば、全てのメンバがpublicだったらいいはずだ。
このケースで、どうやって実現出来るのか説明してみろ。
お前は本当に何も分かってない。最初から躓くと思うぜ。
オブジェクトAのメンバはすべてpublicである。
オブジェクトAのインスタンスa,b,c,dは
・aはbを参照している
・bはaを参照している(a-b間で循環参照)
・cはbを参照している
・dはcを参照している
の状態で、a-b間で循環参照があり、参照はd -> c -> b <-> aとなっている。
これらへの参照は他にはない。
今、dへの参照がなくなり、dのデストラクタが起動された。
この状態で、どのように回収されるのか、説明してみろ。
お前みたいな馬鹿には出来ないと思うぜ。
さっさとJavaScripterの巣に帰れ。邪魔でしかないから。 >>220
単純な共有と循環を区別できるコードを書いてみてごらんよ。
あなたが考えているような簡単なものにはならない。
恐らくはあなたには書けないから。
コード書かずに妄想してるから間違えるんだよ いや違うか。
普通はコード書かずともちょっと考えればそんな間違いしない。
考えずに書くから間違いばかりする。 有向グラフでマークしてトラバースすれば循環がわかるのは単方向リストくらいなものだろ
ドーナツがどうとか言ってるのは無向グラフと混同している JavascriptとC++では要求されるレイヤーが違うので、比較するのは無理だと思う。 複雑な参照を持つシステムってまぁほとんどシミュレーション系で速度も要件に入ってくるんですよ。
糞遅いJavascriptやpythonなんて普通に使いものにならずC++の独擅場なわけですよ。
pythonでAIとか笑っちゃいますね。 >>233
この場合の Python はいわゆるグルー言語でしょ。
高速なコンポーネントのパラメータを指定して組み合わせるだけみたいな使い方なんじゃないの。
高速な計算が出来るコンポーネントは C++ が主流であったとしても、
それをビジネスロジックにさっと適用するという意味での「Python で AI」は現実的だし、
実際よくあることだと思う。 高額なPython屋募集のAI案件は、99%非現実的。
AIを何も分かってな奴が企画したプロジェクト。散々利用されてきた統計学以上の成果など出やしない。
昨今のAIブームは過去のAIブームと同じく破綻プロジェクトばかりなのは言わずもがな。
なぜPythonか。失敗したときにPythonだからと言い訳するため。
そもそも簡単な言語なのに高額で募集する時点で辻褄が合わない。
嘘ついて投資募ってるのは明らか。読売新聞のAI記事読んでると騙す気満々だと分かる。
openCVスレでもpythonから入る奴は何もできやしない。最初から分かりきったこと。フフフ、笑えますね。 結局はコンポーネント間の通信回数を減らすことが肝。しっかりと設計を吟味すれば従来通りのIPCで十分だったりする。 >>235
でもAIってモジュール部分は超簡単なんじゃない? それにそんなもの「作る」って
レベルじゃないから、出来の悪い奴でもいいから一人がC++でモジュール書いていば
OKでやっぱPythonレベルの方が重要なのではないか? そのあたりはpythonのソースコードを見ると分かる
ttps://github.com/python/cpython/blob/master/Objects/weakrefobject.c C++の公式スクリプト言語はPythonだから慣れるしかない。 AIで一番大変なのはデータを食わせることだよな。パイトンでもC++でもなくて
一番重要なのはエサやりして大切に飼いならす人だよ。だから愛がないとできない。
お前等には無理だな。三日やったら課長の机に糞してとんづら。 その学習させた膨大なデータが高額で取引される時代が来るのかね OCamlがあるのだからオッパイソンがあってもいいはずだが。 >>235
ほとんどのAI案件がやばいってのは同意だが
pythonなら言い訳できるってのはねーわw
そもそもAI案件の難しさはプログラム言語がどうのとかそういう問題じゃない。 >>230-231
仮にそれでもJavaScripterよりマシだ。
お前も含めて、JavaScripterには、馬鹿かつキチガイしか居ない。
例>>220,224: 反論することも出来ず、間違いを認めることもなく、ただ逃亡
これをやるからJavaScriptのWebリソースは大半が腐ってる。
俺は知らんがC/C++はWeb上の間違いに異常に厳しかった時代があったと聞く。
それが今も引き続いていて、Web上の正確性を担保してくれているのなら、有り難い話だよ。
ゆとりには「ぼくがおこられなければいい」という幼稚園児並みの知能しかないから、
JavaScriptコミュニティみたいなことが発生する。
あれは最早完全に手遅れで、その状態のゆとりが教える側に回っていることが最悪。
連中は平気で嘘をつく韓国人レベルのモラルしか持ってないし。
結果的に間違いであったにせよ、修正しておかないと、後で読む人の為にならないだろ。
「嘘だと認めなければ嘘ではない」という、韓国人みたいな奴は、キッチリ殺すべき。
間違ったことを書いたら叩かれるのは、長期的に見ればいいことだ。
それがゆとりには分からないだけでね。
あと、わざわざID消して自演しているゴミ、それは余計に目立つぞ。
他の誰もそんなことをしてないから、逆にコテトリになってる。
お前は他でも荒らしまくってるよな。 >>227
一番足りないのは謙虚さなんだけどな。
JavaScripterは本当に馬鹿しかいないから、コードがマジでゴミしかない。
だから糞コードしか書けない馬鹿がつけあがる。
そしてそれを諫める年長者もいない。幼稚園で先生がいない状態だ。
C++は30年の歴史があって、仕様も改訂し続けているのだから、
今の仕様はその中で今一番マシな方法ということになっている。
JavaScripterみたいなぽっと出のゴミがぱっと考えて思いつくような手法を、
今まで30年間誰も思いつかなかったと思うこと自体がキチガイでしかない。 というわけで先に進める。
沸きまくっている馬鹿を振り落とす為に速度を上げるからよろしく。
>>213
> そもそも再帰的なデータ構造じゃないものなら
> 循環参照のしようがないので普通に shared_ptr で良いし
> そういう処理もごく普通によくある
「再帰的なデータ構造ではないとき、循環参照は発生しない」については同意だが、
「循環参照がない場合は、shared_ptrでいい」には反対だ。
これだとC++の速度優位性が無くなるので、俺ならGC言語を検討する。
ただしこれは宗教だからもういい。
本題は、
・shared_ptr(静的共有)必須な構造が、果たしてあるか
だ。木構造で一番身近なファイルシステムを例に取ると、
静的共有(ハードリンク/shared_ptr)と動的共有(シンボリックリンク/getter)のうち、
前者はほぼ使われてないだろ。
これは、ユーザーによる手動管理の場合、シンボリックリンクの方が明示的で使いやすいからだ。
シンボリックリンクは常に最新版を、ハードリンクは常に生成時の対象を参照するところが異なる。
速度的には静的共有の方が優位だとして、動的共有では無理な事例ってあるか?
俺が知っているハードリンクの活用事例は、WindowsUpdateくらいだ。
「動けばいい」なら動的共有の方が適切に思える。
(C++で動的共有はなかなかにきついが、動的言語なら自然に実現出来る) >>245
何故に自分のことと思ったのか知らんけど、自覚が無いよりはあったほうがいいと思うよ。
別スレでID無しにイジメられたんか? >>248
俺から見ればお前がキチガイだし、
ここがお前にとって合わないと思うのなら、お前がここに来るのが間違ってる。
ゆとりはゆとりだけでスレ作れよ。
それがお互い一番幸せな解決だ。
俺には韓国人とゆとりは殺すしかないという結論が出てる。
お前らは邪魔しかしないから。今もそうだろ。 初心者で的はずれな質問かもしれませんがお願いします。
1行に約4000文字,区切りで書かれたファイルがあり、これが1000行あります。
このファイルを1行ごとに別の配列に格納したいのですがfgetsだとchar型になりcharは256文字しか入らないようです…
どうしたら読み込みできるのでしょうか >>250
> fgetsだとchar型になりcharは256文字しか入らないようです
単に間違えたプログラムを書いている。
そのプログラムを提示してみて。 C言語を通らずにいきなりC++を使う初学者は
fgetsやcharに触れるべからず
必ずラッパーライブラリを使うべし >>250
getcを使ってmyfgetsを新たに作る
改行を調べるだけなのでそんなに苦ではない >>247
C++風に考えるとstd::shared_ptrは必要なくなってくるけど、他の言語の真似をしようとすると、必要になるんだよな。
そしてC++は他の言語から呼び出されるから。
そういう部分で必要があるのかも。 スレッド使う場合は、コピーのほうが速くないかよく考えた方が良い。
意外とコピーのほうが速い。 >>253
宗教じみたことは言わないほうがいい。
C++の入出力クラスiostream系の標準機能は失敗した代物との結論が出ている。
C++学習者は FILE* 系の標準機能を優先して使うのが正道。 >>257
iostream 系のどんなところが失敗しているのですか? >>257
あり得ない
ポインタも分からん奴に生char使われてたまるか
fgets使いたいならC言語で基礎を身に付けてから出直して来いや たしかにiostreamはデストラクタで自動的にクローズしてくれるくらいしか
メリットが感じられないから、自分でファイル入出力クラス作ってるわ iostreamはC++のテンプレートクラスが未発達だったころの遺物だよ。STLに含まれない時点でお察しではあるが。
iostreamを使うよりもshared_ptrなどのスマートポインタでFILE*をラップしたテンプレートクラスを使うほうが現代的。
shared_ptr::shared_ptr<FILE>のコンストラクタで第二引数にfclose()を呼び出すdeleterオブジェクトを渡すだけで事足りる。
shared_ptr::shared_ptr<FILE>直使いもいいが、その派生クラスを使って暗黙のFILE*型キャスト演算子を実装すれば、Cコードとの移植性がさらに高まる。
あと、iostreamはios系の様々なフラグがあるが、煩雑で使い勝手が悪い。覚える価値ゼロ。 >>258
速度じゃないか?
使いもしないオペレータのために余計な処理挟むから。
VCについてくるディンカムウェアなんか一バイトごとに仮想関数呼び出してるぞ。 訂正。
shared_ptr::shared_ptr<FILE> じゃなくて、shared_ptr<FILE>でした。
deleterサンプルは以下の通り
struct file_deleter { void operator() (FILE* fp) const {if (fp != NULL) { fclose(fp); } }};
shared_ptr<FILE> fp(fopen(filename, "r"), file_deleter());
// 以下、fp.get() でFILE*にアクセス。 まあでも、明らかな失敗だったら auto_ptr や wstring_convert みたいにとっくに deprecated にされてるよね。 class FILE_Ptr : public ns_shared_ptr::shared_ptr<FILE> {
struct FILEDeleter {
void operator() (FILE* fp) const {
if (fp != NULL) {
fclose(fp);
}
}
};
public:
FILE_Ptr(FILE* fp = NULL) : ns_shared_ptr::shared_ptr<FILE>(fp, FILEDeleter()) {}
operator FILE* () { return get(); }
template<typename T> bool operator == (const T& obj) const { return get() == reinterpret_cast<FILE*>((void*)((intptr_t)obj)); }
template<typename T> bool operator != (const T& obj) const { return get() != reinterpret_cast<FILE*>((void*)((intptr_t)obj)); }
};
void fclose(ns_shared_ptr::shared_ptr<FILE>)
{ >>266を途中で送信してしまった。
ns_shared_ptrは、boostなりstdなりstd::tr1なり自分の好きな名前空間に置き換えを。以下のように。
namespace ns_shared_ptr = boost;
グローバル関数fclose(ns_shared_ptr::shared_ptr<FILE>& fp)を別途作れば、
Cのコードをコピペ利用した時のfclose(fp)多重呼び出しを防止できる。 >>207,208
>>255,256
DOMの話か?500MBは言い過ぎだからとりあえず放置したが、
GC言語は基本的にshared_ptrの仕様だから、その実行エンジンの実装に使われるのは妥当だ。
これをサポートする為、shared_ptrは仕様上は必要だ、というのも同意する。
問題はそれがデータ構造として必要か、という点で、
DOMの場合、HTMLは共有無し/循環参照無しの単純な木だからunique_ptrだけで問題なく構成出来る。
ただしJavaScript側に捕まれている場合、ノードが木から取り除かれた場合にも保持し続けねばならず、
この実装にはshared_ptrを使わないと厳しいだろう。
しかしこれはデータ構造ではなく、JavaScriptの仕様が原因だ。
マルチスレッドのキャッシュについては、これは現時点でのハードウェアの問題で、
単純に言えば共有RAMに対して書き込みをすれば著しく遅くなるだけだ。
これはデータ構造の問題ではないので別に取り扱う必要がある。
(速度低下はshared_ptrの問題ではなく、キャッシュ構造起因)
データ構造について言うなら、shared_ptrの使いどころは、
1. 共有ノードがある
2. 循環参照はない
3. 動的に生成/消滅を頻繁に繰り返す
だと思うんだが、2の為にメッシュ構造とかは基本的にアウトで、
3も基本的にないだろ。
実はあんまり使いどころなくね?って話。 weak_ptr の使いどころを見極めるのが難しい。 >>261
>iostreamはios系の様々なフラグがある
そうそう、今いち、よく定義がわからないんだよね
それに、手元の実装がこのフラグについてまともじゃないかもしれない iostreamを今、作り直すとしたらfilesystemやstring_viewも視野に入れなきゃね C++でよく使われる各オブジェクトのスタックサイズは以下の通り。
stringstreamとfstreamのサイズは無視できない大きさであることがわかるだろう。
・GCC - ubuntu Linux x64
(sizeof(std::stringstream), sizeof(std::fstream), sizeof(std::ostream), sizeof(std::string), sizeof(std::vector<std::string>), sizeof(FILE))=(392, 528, 272, 32, 24, 216)
・Visual Studio 2017 - Windows10 x64
(sizeof(std::stringstream), sizeof(std::fstream), sizeof(std::ostream), sizeof(std::string), sizeof(std::vector<std::string>), sizeof(FILE))=(248, 280, 112, 32, 24, 8) >>273
数百バイト程度は許容できるんじゃないの。
コンテナに入れるわけでもないし。 直近のスレを見れば分かるとおり、C++は複雑怪奇魑魅魍魎だから
プログラミング初学者が手を出したらヤケドしかしない 勉強でヤケドする分には問題ないし、
むしろ沢山ヤケドして危険を避ける能力を身に着けるしかない。
実務でやったらアウトだが。 iostream 文句言われてるけど、atomic に動作するところは thread 並列環境では
そこそこ良いのでは?もちろんその分遅さが気になる場面もあるけど。 iostreamは速度を全く期待せずに使うという
C++らしからぬ面を持ったものだ
sync_with_stdio? はははは 国際化に向かないのが致命的。
これだけで捨てる理由としては十分と思う。 MSVCのstd::arrayがC++11に準拠してくれればいいのに。使えねー。
言語レベルで区間チェックしてくれたら、データ破壊の場所がすぐにわかるのに。 スタティックライブラリAが別のスタティックライブラリBのAPIを使っている場合、ライブラリAにライブラリBをリンク、ビルドして、結果できたライブラリAだけをリンクして、実行ファイルを作る形式が良いでしょうか。
それともラリブラリA、ライブラリBを別々にリンク、ビルドして実行ファイルを作る形式が良いでしょうか。 >>282
>ライブラリAにライブラリBをリンク、ビルドして、結果できたライブラリ
そんなことができるのでしょうか? >>281
msvcのat()関数は範囲チェックしないの? iostream の替わりになるようなデファクトスタンダードが登場していない以上、
ほどほどに付き合っていくしか仕方がないよ。
C スタイルは普段から使うには抽象度が低くて面倒くさい。
printf は std::string を表示するのにさえいちいち c_str を通さなきゃならんのだからな。
書式指定との整合が型システムで保証されないのも古い設計だし。
処理系の方である程度は特別扱いすることで折り合いがついてるけど、
あらためて考えるとだいぶん不格好だと思う。
コンセプトやら何やらが導入されたらもうちょっとマシな入出力ライブラリが出来たりしないもんかね?
提案くらいは出てたりしない? って思ったけど、こないだ江添っちがTwitterで「無い」って言ってた気がする。 現実的にはxmlなど標準的な形式のファイルを扱うライブラリを使うんで本当に低レベルなIOはどっちでもいい >>274
iostreamは肝心な時に使えない橙武者です。
ログ出力するクラスは歌舞伎の黒衣のような慎ましい存在でなければならないのですが、
iostreamはあたかも歌舞伎の花形役者のようなオレ様的存在感を出すので好ましくありません。
実例をあげるならば障害発生した時に、ログ用途でiostream系を使うことがあり得えます。
cout やその他インスタンスが生成されてスタックを多く使うことになります。
つまり、実運用環境とログ埋込環境でメモリ構成が大きく異なる環境になってしまうことが避けられません。
iostreamはマルチスレッド環境など対話デバッグでは追跡しにくい現象をログ出力するのに適さない、と断言できます。
橙武者、黒衣など語の意味が分からない方は、ご自身でおググり下さい。 coutってアクセスするたびに生成するわけじゃないよね? ツリートラバースするのに、再帰使うよりstd::deque使ったスタックのほうが速いな。 >>291
グローバルオブジェクトとしてずっと存在してる 内緒ですけどね。書式設定はprintfのほうがソースが見やすいですよ。 「標準出力への書き込みは遅いから」との理由で、メモリ上にログをため込むことは多いかと思います。
iostream系だと stringstreamを使うことになりますがスタックサイズが割と大きくインスタンス生成のたびに時間もかかります。
さらにいえば、MSVCの場合、snprintf()に比べてstringstreamは書き込みに3倍弱時間がかかります。
本来ならば << 演算子はコンパイル時に型が決まるので書き込みが高速なはずなのですが、
MSVCだとstringstreamがsnprintf()に負ける有様ということです。
なお、Linux GCCの場合、snprintf()とstringstreamは書き込み速度の差は少ないようです。 CとC++で演算子の優先順位が異なる所があります
どこてしょう
もちろん両方に存在するものです >>298 の問題は面白いし俺も答えに興味あるけど >>297 への挑戦とすれば
「C++は完全に理解したけどCの方は知らないよ」で逃げられるかと。 C++の規格はCの規格を参照してるし、Cとの差異も規格の一部になってるので
C++の完全な理解の中に当然含まれる アホなので優先順位の違いはわからないけど、
if ((v=f()) == 0) を if ((v=f()) = 0) とタイポしたとき
c++ だとエラーにならず v が 0 になるのは嫌な感じ if ( 0.equals(v=f()) )
こう書ければいい Cでは代入式はその結果値が左辺値にはならないから v = 1 = 2 みたいな表現は通らない
C++では左辺値になるので通る 昔定数を先に書くことで防げるって聞いたことがあるが
0=(v=f()) 昔からこういう==での判定は
if (S_OK == (result = someApi()) {...}
と定数左で書けという作法もあるけど、
流行らないのは見た目が実行順と逆みたいで妙だからかねえ 〇〇=0 はあるけど 0=〇〇 は違和感しかないからなぁ
バッドノウハウの筆頭だと思う 数学でも 0 = x^2 + 3x - 2 とかあまり書かないな まあそんなクソな書き方するくらいならテストコード書けやって話にはなるわな。 >>304-305
それいつの話だ馬鹿野郎
俺が新兵の頃には、そんなコード書いたら教官からブン殴られてたぞ!! バッドノウハウ……かなぁ…?
定数を左に書く利点は テストより手軽にコンパイルエラーで止められる事だから
個人的には採用してるんだけど
int i = 0;
/* 想定した挙動 */
if ((i = 0) == 0) { printf("%i\n", i); } /* 定数 右: 出力 "0" */
if (0 == (i = 0)) { printf("%i\n", i); } /* 定数 左: 出力 "0" */
/* typo! == -> = */
if ((i = 0) = 0) { printf("%i\n", i); } /* !!! printfが実行されない! (Cでは通らない) */
if (0 = (i = 0)) { printf("%i\n", i); } /* コンパイルが通ら*ない* 助かった! */
/* () 忘れ */
if ( i = 0 == 0) { printf("%i\n", i); } /* !!! 出力 "1" (== (0 == 0) == true) 想定外! */
if (0 == i = 0 ) { printf("%i\n", i); } /* コンパイルが通ら*ない* 助かった! */
そもそも1文字の打ち間違いなんて テストコードの記述そのものでもやりかねないし
(「絶対に間違えない!」なんていう人がいたらコードどころか作文も書いたことない奴ですぜ)
まあ使用が推奨/禁止されてるかはチームに従うとして
ぱっと見で意図が解るようにはしておくとよいかと >>310
そういうのはもはや統合開発環境の仕事なのだよ。
ていうか if の中で代入を書くとか真正のキチガイ。
有 り 得 な い すまんかった >>303 は "v = 1 = 2 みたいな" ではなくて "(v = 1) = 2 みたいな"
括弧忘れたら結合順が変わってしまう 訂正 EmacsのせいでUNIXはDOSに負けたんだっけ。 単体テスト書くと処理時間出るから、何に時間かかってるのかわかっていいよね。 ■ このスレッドは過去ログ倉庫に格納されています