C++相談室 part151

■ このスレッドは過去ログ倉庫に格納されています
2020/05/14(木) 11:53:25.59ID:ZPCfyTux
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part150
https://mevius.5ch.net/test/read.cgi/tech/1584975873/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)

テンプレここまで
2020/06/20(土) 12:38:41.23ID:s3zB5lV1
>>493
Windows使えや。
2020/06/20(土) 13:10:07.38ID:s3zB5lV1
規格を統一するとgcc/clangのような無料コンパイラと差異がなくなってしまうため、MSはC++を主流サポートから外してしまって結果的にC++は落ち目となった。
GUIまで統一したら、今度こそC++は完全に見捨てられよう。
そうなったらWindows支配も終わるかもしれないが、プログラマには大混乱が起きる。
2020/06/20(土) 13:12:32.66ID:s3zB5lV1
>>495
GUI統一の動きがあっても、MSはサポートせずに、MingWだけがサポートする可能性がある。
Qtも自分のアドバンテージがなくなるのでサポートするわけなかろうし。
clangはAppleなのだからiOSやMacに支障を来たすためサポートしないだろう。
結果、gccだけがサポートする変な仕様として終わる。
2020/06/20(土) 13:18:22.13ID:s3zB5lV1
それに、gccには既にGTKがあり、彼らの中では統一規格になっている。
それが彼らの中では世界標準である。
2020/06/20(土) 13:30:02.11ID:u8LBLBzP
c++ってMSの主流じゃね?
C#の方がおこぼれっぽい
2020/06/20(土) 13:33:04.69ID:aXUmPW3Z
またこのキチガイかよ…
連投する度に頭ん中に新しいお花畑でも作ってんのか?
2020/06/20(土) 13:46:04.14ID:hTyaQ2gm
すでにお花畑に埋もれているんだろう
501デフォルトの名無しさん
垢版 |
2020/06/20(土) 16:36:26.09ID:/Eg/RpNH
カーネルがC#になる。
2020/06/20(土) 18:44:23.71ID:bxmHAIN3
どんどんゴミ化していくWin10の究極奥義か
2020/06/20(土) 20:16:12.65ID:+Wzjt0fO
Win10Update作成者本人もなんで領域がRAWになるかわからないとかいう更新入れたくないよなというか強制だし
2020/06/21(日) 00:11:33.65ID:Rbk+jGca
WSL2だけ欲しいけど2004は怖くて入れられない
505デフォルトの名無しさん
垢版 |
2020/06/21(日) 09:18:33.28ID:KK75twmS
>>475
みんな結局JSON使ってる気がする
2020/06/21(日) 09:36:46.75ID:Pcgk88Ti
XMLは実際に扱ってみればわかるが
自由度が高すぎるが故にパーシングがめっちゃ重い
手作業で変更とかされるとなんだかよくわからない
エラーで読めなくなることがあって難儀することが
まれによくある
タグで括るという無駄の多い構造のため必要な保存
情報のサイズに比してファイルサイズがやたらと
でかくなる
等々ロクなことがない
2020/06/21(日) 09:42:48.12ID:9qR4cBA5
だな
2020/06/21(日) 22:56:51.71ID:WahLA6tX
xmlnsの扱いがめんどい
2020/06/22(月) 12:33:37.61ID:Uhqw9X2e
boost::property_treeで使える範囲にしとくんだろうね。
2020/06/22(月) 12:34:51.35ID:pJzisI2b
N4713のD.8にuncaught_exceptionがあるんだけど、理由はなんで?

>>379が言ってたようなRAIIの話で
if (uncaught_exception()) terminate();
else throw system_error{...};
みたいなことすんなってこと?
2020/06/22(月) 12:54:18.39ID:GQVtnPwK
XMLよりJSONのほうが容量小さくなるが、それでも今作ってるアプリではJSONも容量が大きすぎた
けっきょくCSVに落ち着いたわ
2020/06/22(月) 14:19:48.28ID:fPKoMQb1
>>477
ディスクやネットワークの速度は言語を変えても変わんない
Perlとかの激遅言語だと差が出るかもだけど、数値計算しまくったりするシステムじゃない限りは、言語でものすごい性能の差はでない
2020/06/22(月) 17:24:35.40ID:lBtyUm6f
perlってpythonと比べたら10倍近く速くなかったっけ?
2020/06/22(月) 17:37:29.72ID:KMeLbKpH
時と場合と環境とタイミングとプログラムとコンテキストによる
515デフォルトの名無しさん
垢版 |
2020/06/22(月) 18:03:57.06ID:JXDt+qCb
>>483
Tcl/Tk
516デフォルトの名無しさん
垢版 |
2020/06/22(月) 18:06:29.92ID:JXDt+qCb
>>497
GTKは糞
517デフォルトの名無しさん
垢版 |
2020/06/22(月) 18:08:18.53ID:5VJoOXgM
ティックルティーケーと読むのかと思ったら、ティックルチンコらしいな。
その後出てきたのはグレートチンコと読むんだってな。
518デフォルトの名無しさん
垢版 |
2020/06/22(月) 18:08:47.46ID:JXDt+qCb
>>511
JSONも無駄が多過ぎる
C++ならmsgpack
2020/06/22(月) 20:55:06.18ID:jHNWxnNv
>>518
msgpackは直接人が読み書きできないから別物
個人的にサイズが問題になるならmsgpack使うよりzlibとかで圧縮するわ
2020/06/22(月) 22:32:34.35ID:74ajGcn7
>>510
D.8 にも書いてある通り uncaught_exceptions() で同じことができるので、そっちを使えばいい。
わざわざ消してない実装が多いだろうから、たぶんまだしばらく uncaught_exception() も使えちゃうだろうね。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0619r4.html#3.7
2020/06/22(月) 23:25:55.80ID:xsRfWdvc
まともな実装なら[[deprecated]]付けてるでしょ
2020/06/23(火) 05:40:34.32ID:oj2a+YQY
>>520
再入可能バージョンを使えってことね
thx
2020/06/23(火) 10:14:52.18ID:rAKqcV1b
>>519
msgpackはキーが冗長で、結局圧縮が必要なんだよな
テキストであることのメリットを捨てるにはあまりにも中途半端なフォーマット
2020/06/23(火) 10:47:11.02ID:qPEbpbt+
constなメンバー変数ならpublicにしてもいい?
2020/06/23(火) 10:56:31.49ID:rAKqcV1b
後で実装を変更してその変数が不要になったらどうする?
constだからといって不必要に実装を晒していいことにはならない
あくまで教科書的にはこう答えるしかないが、あとはケースバイケースで判断せよ
2020/06/23(火) 11:38:38.63ID:oj2a+YQY
メンバーにconstはあんまり付けないね
static constとかconstexprにするときくらい
書き込みを制限したいなら、それこそ雪駄と下駄で細かく調節できるから
2020/06/23(火) 19:20:38.55ID:60OAlPGb
個人のコードなら全てstruct、全てpublicで良い
仕事、共同、公開コードなら周りにあわせる
2020/06/23(火) 20:12:57.48ID:4z1R/L6q
ランボーだな
2020/06/23(火) 20:19:23.61ID:60OAlPGb
全て自分のコードなら
ポリシーがしっかりしていれば何の問題もない
2020/06/23(火) 20:22:22.86ID:rl0ysbNQ
そのポリシーの帰結がpublicかstructかということだと思うが
何も考えてないのと変わらない
2020/06/23(火) 20:22:26.04ID:6iuxc80n
個人的には、publicにするかどうかはユーザーがアクセスする情報であるかどうかで決めればいいと思うけど
外から見える必要があるなら公開すればいいし
変数で公開するのが気持ち悪ければIsなんとかのメンバ関数作るとか
逆にユーザーが触れる必要のない情報ならconstだろうが公開すべきではない
2020/06/23(火) 20:24:28.42ID:60OAlPGb
>>530
初心者的発想
2020/06/23(火) 20:24:40.50ID:rl0ysbNQ
正直プライベートメンバーがヘッダーから丸見えなC++の仕様はいかがなものかといつも思っている
2020/06/23(火) 20:25:38.50ID:CqSQN5Gg
ヘッダ提供している時点でユーザーに見せたくないものではないよね

隠したいならもっと本格的にやるわ
2020/06/23(火) 20:25:59.71ID:60OAlPGb
ヘッダと実体に分けなきゃいけないのが欠点だと思う
2020/06/23(火) 20:27:30.62ID:CqSQN5Gg
でもjavaやc#みたいに一緒くたにされると、見辛いことこの上ない
2020/06/23(火) 20:31:20.90ID:Rp8Vr+Lo
>>536
テンプレートは嫌い?
2020/06/23(火) 20:32:52.52ID:sbDHiXI+
>>535
それが分割コンパイルというものなのでは?
2020/06/23(火) 20:34:09.42ID:CqSQN5Gg
templateでも長くなってきたら実装分けるだろ
普通はヘッダからさらにincludeするだけだけど、場合によっては分割コンパイルもする
2020/06/23(火) 21:15:05.81ID:K4mymhGD
>>536
そのためだけにインターフェース作ったりしてる
2020/06/23(火) 21:35:01.84ID:oj2a+YQY
数ヶ月前の自分て他人だかんな
なんでこんなアホなことしてんだとムカッ腹立ったりする
2020/06/23(火) 23:28:42.38ID:Rp8Vr+Lo
>>538
分けるべき時は分ける
分けたくない時もある
その自由が無い
2020/06/23(火) 23:32:03.90ID:0n9/qQGG
>>539
分けるだろって
分けるべき時と分けないべきときがある
2020/06/24(水) 05:30:51.33ID:fimjTN9U
コンパイルが重いtemplateはよく分けるな
2020/06/24(水) 07:09:07.40ID:MMfROoXz
明示的な具現化?
2020/06/24(水) 07:16:09.73ID:+7c5yhaJ
>>539
ヘッダからインクルードするだけって
まさかそれで実装を分けたと思ってる?
2020/06/24(水) 07:24:43.03ID:5K2T8Wb8
標準ライブラリが分けられてないのに
どうやって分けるんだよ

使うテンプレートパラメーターがあらかじめ決まってないと実装を分けられないはずなんだが

実装を分けるってのは
コンパイル単位を分けるってことな
2020/06/24(水) 08:16:05.12ID:iulgQyvw
C++のライブラリを更新するとき、新たなメンバ変数を追加するとメンバへのオフセットが
ずれてバイナリ互換性がなくなるといいますが、これを無理やりどうにかする方法って
ありますかね?

理屈上は、オフセットに影響を与えないメモリ位置に各インスタンスのメンバ変数を保持し、
参照、破棄等適宜すればいいと思いますが... ?? もしこれが可能ならば具体例とかを見たい
のですが、うまく探せませんでした。
2020/06/24(水) 08:46:11.21ID:MMfROoXz
メンバ変数をprivateにして雪駄と下駄を用意する
メンバ変数へのアクセスを常に関数経由とすることで
オフセット等の物理的な条件で互換性が失われることを防げる

つーか、ソースコードを変更してるのにバイナリを更新しないのはおかしいだろ
Makefileのバグを疑うべき
2020/06/24(水) 09:35:30.51ID:OmEqu4Is
>>548
普通に追加して再コンパイルさせりゃいいという話じゃなさそうなのはわかるけど
「無理やり」が暗に指していそうな制約も「どうにかする」の指す要件もわからない。
2020/06/24(水) 11:11:37.90ID:RdcHMRga
osの違いを吸収してるようなもんを作ってる場合
何でもフルチンで触らせるとそもそもの意味がなくなるわな
552デフォルトの名無しさん
垢版 |
2020/06/24(水) 11:43:22.15ID:6+kkBVmV
>>548
python の C module の造り方
2020/06/24(水) 12:08:38.76ID:irp07WaX
>>548
COMみたいに、methodだけを外に出して、データは直接は外に出さないようにすればいい。
interfaceの考え方。
2020/06/24(水) 12:13:38.23ID:irp07WaX
>>553
追加。
Win32APIなどの手法を真似る方法もある。
OSの内部構造が修正になってもAPIは互換性を保ててる。
やりとりのための構造体は先頭の方にバイト数を入れるメンバが用意されていて、
以後のメンバの後世が変更になった場合、構造体の末尾に追加していっている。
先頭にバイト数を入れることで、個々の構造体が変化したかだけの影響を受けるため、
ライブラリ全体のバージョンが変化しても全ての関数の仕様を入れ替える必要がなくなっている。
2020/06/24(水) 12:20:34.60ID:sRKtYS7k
>>548
pimplでぐぐれ
556548
垢版 |
2020/06/24(水) 16:28:24.79ID:iulgQyvw
皆さんどうもです。状況は (以下、ライブラリ -> lib アプリ -> app)

lib v1.0 リリース
app v1.0 が lib v1.0 をリンクしてビルド、リリース
lib v1.1 リリース(メンバ追加) <- 今ココ
app v1.0 クラッシュ

というわけで lib v1.1 を出すとき小細工して(でもメンバ変数相当を追加したい)
app v1.0 のクラッシュを防げないか、ということです。
とりあえず lib v1.0 には impl メンバはないです。
2020/06/24(水) 16:41:30.01ID:nJwAdMhi
>>555
pimplでバイナリ互換は保証できないよ
2020/06/24(水) 16:48:55.87ID:nJwAdMhi
>>556
インスタンスをnewしてるのがアプリ側だったら
メンバ追加はほぼ絶望的
無理にやるとしたらメンバのアライメントの隙間に数バイトつっこむぐらい

バイナリ互換とる場合はIFはCにするのが定石だよ
(C++でやるなら上にあるとおりcomとかになって複雑になる)
よくわかってないみたいだから頭下げてアプリにビルドしなおしてもらいな
2020/06/24(水) 17:26:36.53ID:L0Gy/Feu
よく分からん
libは兎も角、appはソースあるのが普通じゃね
リンクしなおしている時点で、コンパイルからし直すのも出来るはず

ヘッダのバージョン合ってなきゃそりゃ転けるわ
2020/06/24(水) 18:00:35.46ID:irp07WaX
>>558
newの変わりに、仮想関数のCreateObject()というメソッドを呼ぶ方式があるね。
2020/06/24(水) 18:18:52.62ID:irp07WaX
1. Pimplの場合:
class CXxx {
public:
 (メソッド群)
protected:
 CImpl *pImpl;
};

2. 別解
使う側 :
class CBase {
public:
 virtual CBase *CreateObject();
 (メソッド群)
};
実装する側 :
class CDerived : public Base {
public:
 CBase *CreateObject(); // 実際にはCDeriveの先頭アドレスをCBase*にcastしたものを返す。
 (データメンバ群)
};
2020/06/24(水) 18:26:04.51ID:OmEqu4Is
>>561
その別解とやら、 CBase のインスタンスを得るためにはまず CreateObject() を呼び出すための
CBase のインスタンスが必要になってて、無理じゃね?
2020/06/24(水) 18:35:10.44ID:fimjTN9U
>>547
プロジェクトの範囲内ではテンプレートパラメータが数種類に限られることも多いからそういう時には明示的インスタンス化が利用できるよ
2020/06/24(水) 18:38:06.77ID:q+GJbQMN
>>549
ライブラリ
って知らない?

>>548
バイナリをいろいろなアプリで今後使う予定ならなるべく実装を隠そう
内部で実体の構造体なりクラスなりをnewで作って
外部に公開するクラスは
単にその内部クラスとのインターフェースだけ行う
後から機能を追加出来るように
function(command, param1, param2)
みたいな関数も用意しておく
2020/06/24(水) 18:57:23.17ID:irp07WaX
>>562
言われてみれば。正しい別解の1つは、
class CXxx {
public:
 static CXxx *CreateObject();
 (メソッド群)
};
だね。
2020/06/24(水) 18:59:39.89ID:wsyC1+3+
>>562
なにいってんだ
返すのはポインタだから実体必要ないだろ
2020/06/24(水) 19:01:25.53ID:QJ36Pf9n
>>566
仮想関数呼ぶのには当然同じクラスの実体が必要

cloneなら仮想関数で実装できる
2020/06/24(水) 19:08:20.34ID:irp07WaX
>>565
すまん、こうでなくてはならなかった:
使う側:
class CBase {
public:
 static CBase *CreateObject();
 (メソッド群)
};
実装側:
class CDerived : public Base {
public:
 (データメンバ群)
};
CBase *CBase::CreateObject() {
 return new CDerived;
}
2020/06/24(水) 19:08:44.81ID:wsyC1+3+
>>567
実体のあるクラスをアップキャストすれば必要ねぇだろバカか
2020/06/24(水) 19:17:24.53ID:QJ36Pf9n
何が目的なんだか
その派生クラスのインスタンスを作りたいから、CreateObject呼ぶんだろ?
呼ぶ前に派生クラスのインスタンスが必要って、鶏と卵じゃないか
2020/06/24(水) 19:19:01.22ID:ML+2IMf2
こっそりlib差し替えとか後が怖いなーと思いましたw
2020/06/24(水) 19:24:18.50ID:q+GJbQMN
>>556
今あるメンバ変数の1個をポインタに置き換える
ここに色々なデータが入った構造体のポインタを置く
これで互換性を保てる
2020/06/24(水) 19:27:44.47ID:QJ36Pf9n
ヘッダにオブジェクトの中身を読み書きするinline関数有ったら危険
inlineじゃなくてもtemplateだとヤバイ

まあtemplateで実体生成されないように実装分離してたらセーフかな
2020/06/24(水) 19:29:28.85ID:q+GJbQMN
当然外から直接アクセスする変数は変えたらダメ
2020/06/24(水) 19:42:58.81ID:q+GJbQMN
ヘッダは基本変えない
不便ならポインタに置き換える変数1個だけ型と名前を変える

あとはライブラリ側のコードのみ変更

アクセス関数を後から増やすなら
クラスのポインタとパラメータをパラメータにしたグローバル関数にする

多少使いづらいが
互換性を考えて設計しなかったツケ
2020/06/24(水) 19:48:51.80ID:e6Wuxio/
>>571
巷のOSとか、定期アップデートがかかるときにこういうので悩んだりしないんですかね?

>>572
おお確かにそれでいいんですかね?

まあ今後新たにライブラリを公開することがあるなら最初から気をつけようってことでw
2020/06/24(水) 21:43:18.10ID:N310/pVU
拡張した方は別の型(派生クラス)じゃあかんのか。
2020/06/25(木) 09:10:26.77ID:TVNlb9r7
>>564
知ってます
当たり前でしょそんなこと!
2020/06/25(木) 10:19:29.66ID:X3nsKEKb
>>572
それは、Pimpl方式だけど、それより、>>568の方が書きやすいし、効率も良い。
2020/06/25(木) 10:26:19.02ID:lze6mCYp
>>579
一から書き直せる条件じゃないんのおわかり?
だいたい >>572 をpimplとは呼ばないでしょ
置き換えないメンバはそのまま見えてるわけだから

あとpimpl論議は飽きた
2020/06/25(木) 12:53:57.93ID:yb+enRFi
>>579
互換性を保つのが前提だから
ヘッダは基本今のまま変更不可

っていう前提条件を理解してから書いてね
2020/06/25(木) 18:36:00.50ID:KZb+gCmD
>>580
書き直せないんじゃ、危険だけど>>572くらいしかないんじゃない?

そんな暗黒魔法使うくらいならapp1.0を再コンパイルする方法を考えるけどね。
2020/06/25(木) 18:41:27.48ID:/eSpQqPW
ヘッダは変更するの前提じゃないの?
バイナリ互換させるの前提なのだから
2020/06/25(木) 19:04:50.22ID:X3nsKEKb
「メンバ変数の一個をポインタに置き換える」
こともヘッダを変更するのが必須になると思うのだが。
2020/06/25(木) 19:07:11.43ID:TznTPNyN
>>584
必須じゃない
2020/06/25(木) 19:13:33.80ID:g2od3l7G
実装側でアクロバットするのは無理やりバイナリ互換させる旧バージョン対応の方で良い

新バージョンの中身にあわせてヘッダを更新しておかないと、負の遺産が延々と続くことになる
2020/06/25(木) 19:14:44.69ID:L+/QiPNH
>>584
やり方次第。
privateのint変数やポインタ変数があるなら、キャストしてぶちこめばいい。
他の変数も似たようなもん。
2020/06/25(木) 19:16:18.79ID:X3nsKEKb
>>587
ええ!!??
2020/06/25(木) 19:27:44.15ID:aCPUEpAO
バイナリ互換をはじめてかんがえた
って感じの人が多くて驚く
2020/06/25(木) 19:27:52.99ID:g2od3l7G
pointerに置き換えたとして、指す先の実体の管理はどうするんだ
元々デストラクタが外部定義されてないと、デフォルトのデストラクタ呼び出しはinline化されてしまっている
2020/06/25(木) 19:32:44.29ID:aCPUEpAO
なんでインラインだと思ったんだか
2020/06/25(木) 19:34:45.97ID:aCPUEpAO
ライブラリ作ったこと無いのかな?
2020/06/25(木) 19:36:15.68ID:g2od3l7G
いや、はじめからバイナリ互換させる前提で設計したライブラリでもない限り、小手先の対応でなんとかなる場面は物凄い限られるよ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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