X



C++相談室 part136
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (ワッチョイ bf81-LHz9)
垢版 |
2018/06/07(木) 23:40:12.36ID:GNQuDMaA0
次スレを立てる時は本文の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
0249デフォルトの名無しさん (ワッチョイ 419f-bAWz)
垢版 |
2018/06/17(日) 11:58:04.60ID:DwTnzOB00
>>248
俺から見ればお前がキチガイだし、
ここがお前にとって合わないと思うのなら、お前がここに来るのが間違ってる。

ゆとりはゆとりだけでスレ作れよ。
それがお互い一番幸せな解決だ。

俺には韓国人とゆとりは殺すしかないという結論が出てる。
お前らは邪魔しかしないから。今もそうだろ。
0250デフォルトの名無しさん (ワントンキン MM92-l11B)
垢版 |
2018/06/17(日) 12:17:06.47ID:I5++lOekM
初心者で的はずれな質問かもしれませんがお願いします。
1行に約4000文字,区切りで書かれたファイルがあり、これが1000行あります。
このファイルを1行ごとに別の配列に格納したいのですがfgetsだとchar型になりcharは256文字しか入らないようです…
どうしたら読み込みできるのでしょうか
0253デフォルトの名無しさん
垢版 |
2018/06/17(日) 14:34:42.11
C言語を通らずにいきなりC++を使う初学者は
fgetsやcharに触れるべからず
必ずラッパーライブラリを使うべし
0255デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/17(日) 15:00:46.90ID:JVUiE6fQ0
>>247
C++風に考えるとstd::shared_ptrは必要なくなってくるけど、他の言語の真似をしようとすると、必要になるんだよな。
そしてC++は他の言語から呼び出されるから。
そういう部分で必要があるのかも。
0256デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/17(日) 15:03:38.90ID:JVUiE6fQ0
スレッド使う場合は、コピーのほうが速くないかよく考えた方が良い。
意外とコピーのほうが速い。
0257デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 15:29:58.46ID:GftzeAnS0
>>253
宗教じみたことは言わないほうがいい。

C++の入出力クラスiostream系の標準機能は失敗した代物との結論が出ている。
C++学習者は FILE* 系の標準機能を優先して使うのが正道。
0259デフォルトの名無しさん
垢版 |
2018/06/17(日) 16:15:29.34
>>257
あり得ない
ポインタも分からん奴に生char使われてたまるか
fgets使いたいならC言語で基礎を身に付けてから出直して来いや
0261デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 17:21:05.94ID:GftzeAnS0
iostreamはC++のテンプレートクラスが未発達だったころの遺物だよ。STLに含まれない時点でお察しではあるが。
iostreamを使うよりもshared_ptrなどのスマートポインタでFILE*をラップしたテンプレートクラスを使うほうが現代的。
shared_ptr::shared_ptr<FILE>のコンストラクタで第二引数にfclose()を呼び出すdeleterオブジェクトを渡すだけで事足りる。
shared_ptr::shared_ptr<FILE>直使いもいいが、その派生クラスを使って暗黙のFILE*型キャスト演算子を実装すれば、Cコードとの移植性がさらに高まる。

あと、iostreamはios系の様々なフラグがあるが、煩雑で使い勝手が悪い。覚える価値ゼロ。
0262デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/17(日) 17:21:36.16ID:JVUiE6fQ0
>>258
速度じゃないか?
使いもしないオペレータのために余計な処理挟むから。
VCについてくるディンカムウェアなんか一バイトごとに仮想関数呼び出してるぞ。
0263261 (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 17:27:10.63ID:GftzeAnS0
訂正。
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*にアクセス。
0266デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 17:54:24.16ID:GftzeAnS0
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>)
{
0267デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 17:59:57.67ID:GftzeAnS0
>>266を途中で送信してしまった。

ns_shared_ptrは、boostなりstdなりstd::tr1なり自分の好きな名前空間に置き換えを。以下のように。
namespace ns_shared_ptr = boost;

グローバル関数fclose(ns_shared_ptr::shared_ptr<FILE>& fp)を別途作れば、
Cのコードをコピペ利用した時のfclose(fp)多重呼び出しを防止できる。
0268デフォルトの名無しさん (ワッチョイ 419f-bAWz)
垢版 |
2018/06/17(日) 18:09:36.34ID:DwTnzOB00
>>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も基本的にないだろ。
実はあんまり使いどころなくね?って話。
0270 ◆QZaw55cn4c (ワッチョイ 2260-m0US)
垢版 |
2018/06/17(日) 18:17:30.15ID:mtjEdwIk0
>>261
>iostreamはios系の様々なフラグがある
そうそう、今いち、よく定義がわからないんだよね
それに、手元の実装がこのフラグについてまともじゃないかもしれない
0272デフォルトの名無しさん (ワッチョイ edb6-5g47)
垢版 |
2018/06/17(日) 18:54:25.32ID:ipfkqsZ+0
ビジネスで優秀な人材育成する上司は何を教えているのか?
https://www.youtube.com/watch?v=apxtSqxjw08&;t=13s
美容師の楽しさ再発見!やる気スイッチが入る働き方セミナー
https://www.youtube.com/watch?v=DGzXQT799oY
マクドナルド伝説の店長が教える、最強店長になるために必要なこと
https://www.youtube.com/watch?v=0wMbR7JIeeQ&;t=3154s
『上司が伝えるべき 一番大切なこと』
https://www.youtube.com/watch?v=xsfJ-ZC42pQ&;t=1199s
0273デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 19:38:39.93ID:GftzeAnS0
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)
0274デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/17(日) 19:51:08.65ID:JVUiE6fQ0
>>273
数百バイト程度は許容できるんじゃないの。
コンテナに入れるわけでもないし。
0275デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/17(日) 19:53:22.73ID:JVUiE6fQ0
>>268
ないよ。
0276デフォルトの名無しさん
垢版 |
2018/06/17(日) 19:54:46.50
直近のスレを見れば分かるとおり、C++は複雑怪奇魑魅魍魎だから
プログラミング初学者が手を出したらヤケドしかしない
0277デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/17(日) 20:02:30.99ID:GftzeAnS0
勉強でヤケドする分には問題ないし、
むしろ沢山ヤケドして危険を避ける能力を身に着けるしかない。
実務でやったらアウトだが。
0282デフォルトの名無しさん (ブーイモ MM62-hu3a)
垢版 |
2018/06/17(日) 21:52:06.00ID:PyYPwpSkM
スタティックライブラリAが別のスタティックライブラリBのAPIを使っている場合、ライブラリAにライブラリBをリンク、ビルドして、結果できたライブラリAだけをリンクして、実行ファイルを作る形式が良いでしょうか。
それともラリブラリA、ライブラリBを別々にリンク、ビルドして実行ファイルを作る形式が良いでしょうか。
0287はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 066f-Bw3Y)
垢版 |
2018/06/18(月) 00:02:38.25ID:CYJOSJS20
iostream の替わりになるようなデファクトスタンダードが登場していない以上、
ほどほどに付き合っていくしか仕方がないよ。

C スタイルは普段から使うには抽象度が低くて面倒くさい。
printf は std::string を表示するのにさえいちいち c_str を通さなきゃならんのだからな。
書式指定との整合が型システムで保証されないのも古い設計だし。
処理系の方である程度は特別扱いすることで折り合いがついてるけど、
あらためて考えるとだいぶん不格好だと思う。

コンセプトやら何やらが導入されたらもうちょっとマシな入出力ライブラリが出来たりしないもんかね?
提案くらいは出てたりしない? って思ったけど、こないだ江添っちがTwitterで「無い」って言ってた気がする。
0289273 (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/18(月) 06:12:18.90ID:q6319o4n0
>>274
iostreamは肝心な時に使えない橙武者です。

ログ出力するクラスは歌舞伎の黒衣のような慎ましい存在でなければならないのですが、
iostreamはあたかも歌舞伎の花形役者のようなオレ様的存在感を出すので好ましくありません。

実例をあげるならば障害発生した時に、ログ用途でiostream系を使うことがあり得えます。
cout やその他インスタンスが生成されてスタックを多く使うことになります。
つまり、実運用環境とログ埋込環境でメモリ構成が大きく異なる環境になってしまうことが避けられません。
iostreamはマルチスレッド環境など対話デバッグでは追跡しにくい現象をログ出力するのに適さない、と断言できます。

橙武者、黒衣など語の意味が分からない方は、ご自身でおググり下さい。
0290デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/18(月) 08:25:55.66ID:Tb7Gp3zL0
io_contextで世界が変わる。
0291デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/18(月) 08:29:09.26ID:Tb7Gp3zL0
coutってアクセスするたびに生成するわけじゃないよね?
0292デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/18(月) 08:34:19.02ID:Tb7Gp3zL0
ツリートラバースするのに、再帰使うよりstd::deque使ったスタックのほうが速いな。
0293デフォルトの名無しさん (ブーイモ MMb6-pMQN)
垢版 |
2018/06/18(月) 08:36:26.28ID:h2dlgwUxM
>>291
グローバルオブジェクトとしてずっと存在してる
0296デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/18(月) 11:02:34.48ID:q6319o4n0
「標準出力への書き込みは遅いから」との理由で、メモリ上にログをため込むことは多いかと思います。
iostream系だと stringstreamを使うことになりますがスタックサイズが割と大きくインスタンス生成のたびに時間もかかります。

さらにいえば、MSVCの場合、snprintf()に比べてstringstreamは書き込みに3倍弱時間がかかります。
本来ならば << 演算子はコンパイル時に型が決まるので書き込みが高速なはずなのですが、
MSVCだとstringstreamがsnprintf()に負ける有様ということです。
なお、Linux GCCの場合、snprintf()とstringstreamは書き込み速度の差は少ないようです。
0303デフォルトの名無しさん (ワッチョイ c27c-TqnL)
垢版 |
2018/06/18(月) 21:06:09.32ID:wRZSUlvR0
Cでは代入式はその結果値が左辺値にはならないから v = 1 = 2 みたいな表現は通らない
C++では左辺値になるので通る
0305デフォルトの名無しさん (ワッチョイ 4223-PZZX)
垢版 |
2018/06/18(月) 21:25:53.85ID:xdRdwSco0
昔からこういう==での判定は
if (S_OK == (result = someApi()) {...}
と定数左で書けという作法もあるけど、
流行らないのは見た目が実行順と逆みたいで妙だからかねえ
0310デフォルトの名無しさん (ワッチョイ ad2d-QRh3)
垢版 |
2018/06/19(火) 00:56:21.64ID:jJOU+tvI0
バッドノウハウ……かなぁ…?
定数を左に書く利点は テストより手軽にコンパイルエラーで止められる事だから
個人的には採用してるんだけど

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文字の打ち間違いなんて テストコードの記述そのものでもやりかねないし
(「絶対に間違えない!」なんていう人がいたらコードどころか作文も書いたことない奴ですぜ)

まあ使用が推奨/禁止されてるかはチームに従うとして
ぱっと見で意図が解るようにはしておくとよいかと
0312303 (ワッチョイ c27c-TqnL)
垢版 |
2018/06/19(火) 01:34:04.88ID:6qgw6hGx0
すまんかった >>303 は "v = 1 = 2 みたいな" ではなくて "(v = 1) = 2 みたいな"
括弧忘れたら結合順が変わってしまう 訂正
0313デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 03:10:51.39ID:WKXXm+ar0
統合開発環境ってEmacsのことだっけ。
0315デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 05:50:29.80ID:WKXXm+ar0
単体テスト書くと処理時間出るから、何に時間かかってるのかわかっていいよね。
0316デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 05:52:35.58ID:WKXXm+ar0
やはり一番時間がかかるのはIOだから、IO少なくするのが一番よさそう。
std::vectorなんか全体コピーしても余裕の速さだから気にする必要なかったんや。
0321デフォルトの名無しさん (スップ Sd62-Gye4)
垢版 |
2018/06/19(火) 10:45:51.92ID:x0u1iMAyd
世の中いろんなコーディングルールがある

ifの中は副作用のあるコード禁止とか
goto禁止とか
3項演算子禁止とか
1個の関数は○○行以内とか
変数名は○○文字以内とか

実際に業務で書かない人が決めたりするからたちが悪い
0322はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 066f-Bw3Y)
垢版 |
2018/06/19(火) 11:00:52.67ID:2U1bfNZa0
if の条件式の中で代入することは勧められない書き方だと思うけど、
「言語仕様に照らして完全に正しいけど間違いやすい書き方」にいちいち警告を出されるとうんざりする。
オプションで強めのチェックにしたときならともかく、デフォルトでだぞ。

かといって個別に警告の有効・無効のオプションを書くのも面倒くさいしなぁ。
0323デフォルトの名無しさん (ブーイモ MM6d-nvpi)
垢版 |
2018/06/19(火) 14:29:42.98ID:mTWnJSOLM
俺も定数との比較なら
if ( 0 == buf )
って定数を左に書くようにしてる
理由は>>310と同じ意図しない代入防止
0324デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 15:21:42.83ID:eYArWI+v0
テスト書けば防げるよ。
0325デフォルトの名無しさん
垢版 |
2018/06/19(火) 17:52:06.99
自動的に静的チェックツールかけとけば教えてくれるよ
0326デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/19(火) 18:32:24.93ID:QaAZlBtz0
関数の戻り値を保存した一時変数を使わなかっただけで警告出されるのは地味につらい。かといって警告を抑止するのも悩ましい。
以下のような感じ。

void test()
{
int foo = bar();
return;
}
0336デフォルトの名無しさん (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/19(火) 20:51:33.23ID:QaAZlBtz0
相談する時は、「なんでそんなところ行ったんだ」などと“そもそも論”を始めて責任所在の確定に情熱を傾ける後ろ向きで生産性ゼロの人に相談することは避けなければならない。
これが私の設問の真意。以下が回答。

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ItemTemplates\VC\Windows Store\1041\BasicPage\BasicPage.xaml.cpp:97
(void) sender; // 未使用のパラメーター
0340326 (ワッチョイ 45d2-Bw3Y)
垢版 |
2018/06/19(火) 21:03:09.63ID:QaAZlBtz0
補足すると、マクロ定義によって戻り値が使われなくなることがある場合の警告を想定。
>>336 であげた BasicPage.xaml.cppの事例は厳密には関数の仮引数を使わない場合の警告なので若干違うが、対処法は同じ。

#define OUTPUT(x)

void test()
{
int foo = bar();
OUTPUT(foo);
(void)foo;
return;
}
0342デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 21:12:21.11ID:eYArWI+v0
>>339
そのコードにエフェクトがあるならテストできるのではないでしょうか。
0343デフォルトの名無しさん
垢版 |
2018/06/19(火) 21:18:56.08
>>339
そういうのはコンパイル時にWarning出るから本線にマージする前には見つかるでしょ
0348デフォルトの名無しさん (ワッチョイ 4223-PZZX)
垢版 |
2018/06/19(火) 21:42:40.31ID:j1n9w5rn0
>>339
if (buf = 0) { A }

・buf がゼロの時 A が実行されないと実行結果(出力など)が正しい結果にならない場合
・bufが非ゼロでここでゼロにされると以下同文

この2つの場合は結果がおかしいからテストで見つかる。
結果は正しいが見つけにくいリークが発生するとか
ここ間違えても結果は(常にではないが)多くの場合正しい
とかだと静的/動的カバレッジで見るしかないね。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況