C++相談室 part161

■ このスレッドは過去ログ倉庫に格納されています
2022/05/21(土) 21:23:29.59ID:kYXfaM+5
前スレ
C++相談室 part160
https://mevius.5ch.net/test/read.cgi/tech/1649979572/
2022/09/28(水) 00:21:27.19ID:2Lj4foK2
>>784
多くの言語は関数定義かそのままインターフェース宣言を兼ねていて一元化されてるよね
バラバラに用意することこそ不自然なのよ
2022/09/28(水) 00:52:38.13ID:qgMCZEH2
いや俺はインターフェースは簡潔にヘッダーにまとまってる方が良い
管理が二重になっている云々は同意せんでもないが
同一性はコンパイラがチェックしてくれるので全く問題なし
ドキュメントの自動生成ってリアルタイムに更新してくれるんかいな?
Doxygenみたいなのを想像してるんだが?
2022/09/28(水) 00:54:10.34ID:qgMCZEH2
C++に慣れすぎて実装とインターフェースが混在してるソース見ると
俺は読みたくなくなるんだが?
2022/09/28(水) 00:57:52.51ID:ipyGSCwr
>>787
めちゃめちゃわかりすぎる
関数なりクラスなりの定義部分だけ切りだして別ドキュメントにまとめてくれや(’A’)
っていう気分にいなる
2022/09/28(水) 01:57:05.38ID:wKFGQzb0
>>785
いや兼ねていてというか、ない
だからサポートするソフトが何らかの方法で提示してるんだけど、必ずしも見やすくなってないのは問題
2022/09/28(水) 02:35:16.76ID:koSj9wX0
>>768
ヘッダを分けるのは最初は処理系の実装上の都合だったのは事実だと思う。
素朴なオブジェクトファイルは名前とアドレスの組でしか管理していない。
具体的な型をやりとりする仕組みは必要で、それがヘッダファイル。

リンカなどのツールチェインが充実していないのを
コンパイラとプリプロセッサがカバーする形なのでツールチェイン全体が上手く連携できるなら
ヘッダという仕組みは無くても良い。

それはそれとして処理に必要かどうかと言語の表現はまた別問題だ。
原理的に必要かどうかだけで言うならバイナリエディタだけあればプログラムは作れることになってしまうよ。
言語は機械に処理させる以上に人が読み書きする。

もちろんどんな言語が分かり易いかは人によるだろうけども
C++ に満足している C++ ユーザは実装とインターフェイス分離することを利点だと考えている場合は確実に多いよ。
私もそうだし。
2022/09/28(水) 05:55:54.63ID:8U6H9Gn3
単にヘッダファイルに慣れていて愛着があるだけです
冷静に考えれば分かります
他の言語はヘッダファイルがなくても機能しています
つまりヘッダファイルは不要なものです
他の言語はヘッダファイル方式を採用しませんでした
つまりヘッダファイルを採用するに値するアドバンテージはありません
2022/09/28(水) 08:10:47.02ID:PNF1OAD8
今は必要に応じてIDLを使うようになっているだけじゃない?Protobufぐらいしか知らないけど。
2022/09/28(水) 08:51:33.64ID:qgMCZEH2
>>791
C++もヘッダに実装書けば似たようなソースになるけど
読み難いんだってば
2022/09/28(水) 09:19:16.30ID:H8fqr1nL
c#のプロジェクト、実装してから設計起こした様なグダグダなのばっかになってるよね
pythonだとそうはならん気がするけど
2022/09/28(水) 22:49:08.92ID:6+yt9OFm
obj や lib だけを提供する場合は、ヘッダは絶対に必要かと
他の言語ではどうしていますか?
2022/09/29(木) 03:41:22.05ID:6tct/z4w
ヘッダは無くてもいいがある方が便利なときがある

使い回すマクロの定数とか定義とかヘッダに書くのが一般だし
誰かが書いてたけどヘッダファイルに関数の説明とか書くスタイルなら
そこだけ見れば済むようになるし

無くても困らないけど結局は
include xxx.c なんてソースコードを見ることなると思う
2022/09/29(木) 03:46:51.96ID:6tct/z4w
>>795
javaは起動するときに.classファイルの中にある関数名を見てるのが
通常じゃないのかな
2022/09/29(木) 04:34:33.18ID:MD5zUQsY
ラムダ式でコピーキャプチャした変数ってなんでデフォルトで immutable なの?

あとそれに関連してるかもしれないけど、const int a があったとして、a をコピーキャプチャして mutable をつけたラムダ式の中で a を変更しようとすると許されないんだけど、これもなんで?
2022/09/29(木) 06:34:14.97ID:Jka8tyPG
最初にラムダ入れた時の設計ミス
2022/09/29(木) 07:34:10.57ID:u1XdWODd
ミスか?
俺はGJと思ったぞ
constの逆は欲しかった
明示的に書き込み許可すんの
2022/09/29(木) 08:13:36.08ID:HMWtGy3T
>>795
ドキュメントを配る
2022/09/29(木) 09:51:48.04ID:r+IaQb6m
ヘッダなんて特別なものはなくて
includeディレクティブがあるだけ
2022/09/29(木) 13:54:32.28ID:o1fQB+Qf
C++11以前なのでoverride演算子がないソースコードなのですが、
派生クラスでオーバーライドされている関数を簡単に見つける方法って
ありますか?
virtual関数を1つずつgrepするしかないですかね。
2022/09/29(木) 14:30:55.43ID:o/ss6osA
>>803 何の前提も無ければ自分がソース持ってないところでオーバーライドされてる可能性もあるので、
いろいろ前提を絞らないと無理かと。
override (「演算子」じゃなくて「キーワード」)があったとしても、付け忘れてる可能性もあるし。
2022/09/29(木) 15:19:58.87ID:o1fQB+Qf
>>804
失礼、修飾子でした。
やっぱそうですよね。
継承が3階層あって、その中間階層クラスのメンバ関数なので調べにくいのですが、
地道に1つずつチェックしようと思います。
2022/09/29(木) 15:27:09.76ID:OAAH5wr1
ヘッダに実装が書かれててもエディタでショートカット1個押して折りたたむだけでインターフェースすぐわかるくね?
2022/09/29(木) 17:04:17.17ID:nKyEXpsu
まっとうならバイナリなりだけ開発環境でインポートすれば、
綺麗にインターフェイスが見える。
2022/09/29(木) 17:12:42.79ID:xXycU9Ev
共有オブジェクト (ダイナミックリンクライブラリ) の段階にまでなってしまうと型は別のところから与える必要があって、
基本的にはビルドの時に型情報を表すなんらかのファイルも生成できるけど、めんどいのは言語をまたぐときなんよね。
Windows API はいろんな言語から使えるような (バインディングの生成元に出来るような) メタデータを提供するという形で
対処しているのでこのへんは Windows API に限らず使いやすいように規格化や環境整備が進むことを期待している。
809803
垢版 |
2022/09/29(木) 17:14:04.54ID:o1fQB+Qf
今はLinuxでgcc+vimを使っています。
どういう環境なら見えますか?
2022/09/29(木) 18:21:37.90ID:YHMprl0j
gtagsとか?
2022/09/29(木) 21:13:35.71ID:xXycU9Ev
>>809
近頃は vim も LSP に対応してるはずだから clangd と合わせて使えばいいんでないの。
わいは vim についてはよう知らんけど VSCode では出来ているから原理的には出来るはず。
2022/09/29(木) 21:39:32.67ID:o1fQB+Qf
>>810,811
似たようなツールでdoxygenを使ったら簡単に見つけれるようになりました~
ありがとうございます!
2022/09/29(木) 21:44:06.62ID:YHMprl0j
似てねーw
2022/09/29(木) 21:59:47.36ID:xIdOGMqx
ええ…
815デフォルトの名無しさん
垢版 |
2022/10/03(月) 10:37:30.67ID:BGisZcin
>>795
obj と lib と h (hpp) だけじゃ不十分
バージョン管理も必要
これ重要
816デフォルトの名無しさん
垢版 |
2022/10/03(月) 10:40:19.01ID:BGisZcin
>>790
template ですね判ります
2022/10/05(水) 11:46:44.33ID:qhw2L+Ej
サイズが可変な自作クラスXのvectorを持ちたいとします。
このとき、Xの実体をいくつかvectorに入れて不用意に各要素のサイズを変更すると、メモリの割り当てがおかしくなりますよね?
実体ではなくポインタを持つ以外のワークアラウンドはありますか。
2022/10/05(水) 11:58:22.13ID:q7thXXzU
>>817
メモリの割り当てがおかしくなると思う事例をコードで説明して。
2022/10/05(水) 12:31:37.02ID:Ghll8vG9
>>817
「サイズが可変なクラス」の簡単な具体例を教えてくれないかしらん?
2022/10/05(水) 12:38:22.59ID:zqJzN+DI
>>817
出来ます
Xの参照(ポインタ等)のベクターを持ちます
Xのサイズが可変でバラバラでも構いません

もしXのサイズに上限値があるならば
別の方法としてその上限値サイズのベクターを用意する方法もあります
2022/10/05(水) 12:52:15.30ID:qhw2L+Ej
>>819
boost::multi_array の resize
2022/10/05(水) 12:53:20.63ID:qhw2L+Ej
>>820

それは>>817の最終行の冒頭と何が違いますか
2022/10/05(水) 13:05:31.97ID:q7thXXzU
sizeof の結果は常に定数なんだよね……。
https://timsong-cpp.github.io/cppwp/n3337/expr.sizeof#6
(C では VLA まわりで定数にならない場合もあってその挙動を拡張として取り入れている C++ 処理系もある。)
そういう意味ではサイズが可変なクラスは存在しない。

>>821
boost::multi_array もそれ自体の大きさは一定。
内部的にはポインタで保持してる。
2022/10/06(木) 11:24:20.53ID:0pxze5TV
やっぱり817が思ってる「おかしくなりますよね?」の最小コード提示してもらわないと
実はそれおかしくならないって結論になりそうなんだが?
2022/10/06(木) 14:37:24.06ID:BJfOFqw4
つまりおかしくなる理由が分からない人が相談に答えようとしているわけだな。
2022/10/06(木) 15:08:29.15ID:cWE4RcCn
>>819,821,823の流れで解決してると思うのだが
>>817が返答も何もしないので>>824のようなのが出てくる
2022/10/06(木) 18:12:29.65ID:nyTo+ttU
「サイズ(sizeof)が可変なクラス」なんて存在しないから817が何かを勘違いしてるのは確かだが
何をどう勘違いしてるのか分からんからお前さんの信念でコード書いてみなって話だろ
別におかしくない
2022/10/06(木) 21:12:38.87ID:2ZLAwlmb
>>821>>817の考えていることは明らか
>>823以上は蛇足だよ
2022/10/07(金) 02:21:50.23ID:qb/V/k6I
>827
単にお前の読解力の話でしかなかったのか。
「サイズが可変な」はvectorに掛かってると考えるだろうふつう。理由は
> 「サイズ(sizeof)が可変なクラス」なんて存在しないから
と自分で指摘してるとおり。
2022/10/07(金) 06:51:34.90ID:iCJcr8aJ
「サイズが可変な」はクラスに掛かってると考えるだろうふつう。vectorは当然サイズ可変なんだから
2022/10/07(金) 07:35:25.67ID:BBv/2c76
sizeof(std::vector<T>)なんて気にせんだろふつー
2022/10/07(金) 07:47:52.68ID:4lX0Ypwn
まあクラスのサイズが変わるようなイメージだったよね
2022/10/07(金) 08:23:09.11ID:0jEkBwds
コード見せろ、この日本語が分からない奴に
このスレは無理
2022/10/07(金) 08:23:45.29ID:2UgM0KPC
質問者です
皆さんのおかげで解決しました
ありがとうございます
2022/10/07(金) 08:24:03.77ID:2UgM0KPC
もうこの話は終了でよろしくお願いします
2022/10/07(金) 11:13:53.12ID:p6wqSRzL
817の類似
https://ideone.com/81vcNn
e1, e2 と list の要素は別物だけど (2) の操作で list も同じく反映するようにするには
list を vector<X*> として ポインタ渡す他に何か手段あるのかな
2022/10/07(金) 11:34:57.30ID:fogpWmkA
std::vectorもboost::multi_arrayも要素数の変更ができるけど、その可変可能個数要素を格納する領域はクラスのインスタンスとは別のヒープ領域に確保されるようになっていて、クラスのインスタンにはそのヒープ領域へのポインタが格納される
したがって要素数を変更してもクラスのインスタンのサイズは変わらない
だよね?
2022/10/07(金) 11:35:56.48ID:fogpWmkA
インスタンじゃなくてインスタンス…
2022/10/07(金) 11:42:47.63ID:Y5jy7O5b
>>837
なぜ上で書かれてるのと同じことを書きたくなったの?
2022/10/07(金) 12:34:55.78ID:UqkGeV53
>>836
listに手を入れるとか手段はあるだろうけどそもそも
> list を vector<X*> として ポインタ渡す
で何が問題なのかを書いた方が良いかと
2022/10/07(金) 12:43:53.29ID:p6wqSRzL
>>840
自分で質問しといてなんだけど、たいした問題点でもなかったりするんだよな…

vector<X*> list; だと要素をアクセスする際に記述が煩雑になるところ
 list[i]->size(); ←おけ
 list[i]->push_back(hoge); ←おけ
 (*list[i])[j]; ←きもい
2022/10/07(金) 12:54:10.56ID:p6wqSRzL
実体のポインタを list に詰まず new したものを詰んだ場合
お漏らしやタングリングポインタになるかもしれんってのもあるかな
これだと問題点が前提とは別のところになりそうではある
2022/10/07(金) 13:55:22.13ID:WQmSj+WJ
>>841
ラッパー書きゃよろしいがな

template <typename T>
class Vector: private vector<T>
{
using Base_ = vector<T>;
public:
using Base_::push_back;
using Base_::size;
const typename remove_pointer <T>::type &operator [] (size_t i) const {return *Base_::operator[] (i);}
typename remove_pointer <T>::type &operator [] (size_t i) {return *Base_::operator[] (i);}
};

Vector<X*> list;
list[i]->size();
list[i]->push_back(hoge);
list[i][j];
2022/10/07(金) 14:39:47.78ID:UqkGeV53
>>841
>  (*list[i])[j]; ←きもい
list[i]->operator [](j) ← う~ん、もっときもいかw

>>842
まあ今時生ポインタは使わんわな
shared_ptr とかを入れれば多少安全かと
2022/10/07(金) 19:06:21.61ID:E6DqXtFD
>>827
http://www.kouno.jp/home/c_faq/c2.html#6
のことでしょ?
これはもう C89 の昔から言われ続けており、太古の C99 でも
http://seclan.dll.jp/c99d/c99d04.htm#dt19990726
のとおり導入されたわけですし

今更なんですけれどね
2022/10/07(金) 19:21:05.99ID:0j3FZIjL
>>834
どう解決したのかコメントを求む
まだ憶測他で引っ張ってるし
2022/10/07(金) 19:57:27.07ID:T/Xux0J0
>>845
それはただのポインタトリックであってsizeof(info_t)が可変になる訳じゃない
というかそのページでもsizeofのこと説明してんじゃん
相変わらずの無能っすね
2022/10/07(金) 20:10:14.06ID:Znh4X5V+
>>847
元の質問>>817はサイズが可変としか言っていない
つまりsizeofが固定であり可変でないという話こそどうでもよい話
本件は>>845氏の指摘する可変なサイズの構造体を作れる話が適切に該当していると思う
2022/10/07(金) 21:32:58.03ID:WQmSj+WJ
>>819と聞いて本人は>>821と答えてるのに
何でそんな解釈を無理やりしてるのかサッパリ分からん
2022/10/08(土) 01:45:23.92ID:wlHp0G63
>>841
思い出したけど boost::ptr_vector なるものもある
2022/10/08(土) 03:10:20.17ID:fnM9fLAu
クラスメンバBの初期化が終わる前に、メンバAのコンストラクタにBのアドレスを渡すのって合法ですか?
2022/10/08(土) 08:08:39.60ID:i+QsN2sY
マルチアレーで思い出したけど、多次元配列クラスのSTL入ってどうなった?
boostとか自作クラスで対応せよってのは暴論だぜ
前者はパフォーマンス微妙だし管理されてない、後者はそれ言うなら何でもそうじゃん
2022/10/08(土) 10:25:38.57ID:a+ry7eGB
>>851
アドレス渡すだけなら合法
中身触ったら違法
2022/10/08(土) 13:47:19.43ID:wlHp0G63
>>852
template <typename T, size_t N0, size_t N1>
using multi_array = array <array <T, N0>, N1>;
2022/10/08(土) 14:59:34.51ID:0p5f7aQJ
>>854
センスね~~~
2022/10/08(土) 15:04:31.64ID:wlHp0G63
>>855
ではセンスある解を!
2022/10/08(土) 15:08:15.47ID:a+ry7eGB
>>852
std::mdarrayのことなら揉めに揉めて伸びに伸びて今は一応C++26の予定
でもまだグチグチ揉めまくって収拾がつかなそうだからもう無理じゃないかな
代わりにstd::mdspanっていう配列に被せるガワが入りそう
2022/10/08(土) 15:56:11.12ID:Ys4Rhd8B
各次元の長さが可変で、全添字の走査が速くて、メモリの並びがFortran流かC流か選べるだけで良いのに何を揉める必要があるのか
2022/10/08(土) 16:31:31.20ID:wlHp0G63
その程度なら自前で直ぐに作っちまいそうだが
標準に入ってることが意味あるんだろうな
2022/10/08(土) 18:03:00.23ID:Ys4Rhd8B
そりゃそうじゃね
「std::vectorよりも自作の配列クラスの方が優れてる」という主張が本当だったことがない
2022/10/08(土) 19:46:47.28ID:WoHyAHa2
>>849
無能君はひっこんでなさい

>>848
ですよね!
862849
垢版 |
2022/10/08(土) 20:25:53.87ID:wHqQf0MD
すいませんでしたw
2022/10/08(土) 21:43:59.65ID:cYIJtZRn
>>862
こちらこそ申し訳ございませんでしたw
2022/10/09(日) 00:52:23.28ID:KNQys/Sq
SIMD まで自分ではやりたくないのでnumpyを呼ぶのほうが早い
2022/10/09(日) 17:16:44.85ID:gpj8txwq
>>864
じゃあ全部Pythonでよくねーか?
2022/10/09(日) 20:20:03.73ID:30oWykTj
>>865
実際自分にとってはそんな感じですね。C++でpython とcudaとかopenmpを糊付けしている感覚があります
867デフォルトの名無しさん
垢版 |
2022/10/14(金) 14:32:13.11ID:hVSCfGeq
set, mapというデータ構造があります。
mapはキーと値のペアをハッシュテーブルや2分探索木に格納しているのでしょうか?
2022/10/14(金) 15:00:32.18ID:zHYXwlQW
平衡二分探索木です
ハッシュテーブル版はunordered_*です
2022/10/14(金) 15:09:19.24ID:hyLjfQu2
ハッシュテーブルの方が大抵の場面で速いと思ってええんか?
2022/10/14(金) 15:26:57.00ID:rgl2oNFZ
>>869
データの性質や使い方によるのでなんとも言いにくいが基本的にはハッシュテーブルが速いことは多い。
差し替えるのは簡単だろうし、やりたいことをとりあえずやってみて測定すればいいんでね?
2022/10/14(金) 15:33:11.96ID:IS1pk00F
>>869
実際にベンチマーク取らないとわからない。
基本的には種類が少ない場合は計算の軽い探索木が、多い場合は定数オーダーのハッシュが有利。
2022/10/14(金) 19:23:56.82ID:6Xf8KnhS
>>871
ハッシュテーブルのサイズ、という地雷的制約は好まないのですけれどもね
2022/10/15(土) 03:19:05.65ID:nP2nOTvD
std::map::operator[] は O(long(N)) のオーダーなんだが、
std::unorderd_map::operator[] のオーダーは平均で O(1) 、最悪で O(N) ということになってんよね。
意図的に最悪を引き当てる、つまり攻撃に晒されるような状況では unorderd_map のほうが不利になる可能性もある。
2022/10/15(土) 18:57:25.60ID:b3v/HVBd
C++の例外処理は、class SomeClass {}; と中身の無いクラスであっても、
throw SomeClass{}; をcatch(SomeClass) {・・・}
で受け取ることが出来るらあしいけど、
どういう仕組みでcatchは、例外の種類を識別してる?
"SomeClass"のようなclass名の文字列のポインタでも一緒に渡している
のだろうか?
typeid(x)は、RTTI(実行時型情報)が必要で、仮想関数が定義されて無いクラス
に対しては上手く働かないのではなかったっけ?
2022/10/15(土) 21:57:03.29ID:QGPaA4bd
まず基本を禿の本でも規格票でも読んで
C++例外処理ってそもそも何ってとこをわかってから
出直したら? そんな有様じゃマトモなレス付かないよ
2022/10/15(土) 23:57:29.06ID:xWZqYwiR
>>874 typeid と同等の情報で照合すれば可能ではあるんだから、何を不思議に思うことがあるのか。
「上手く働かないのでは」なんて言うぐらいならコード書いて確かめればいいだろうし。
2022/10/16(日) 01:59:22.59ID:SvF0Fhwf
>>874
例外を送出してスタックの巻き戻しをするのは例外を送出する側 (受け取る側ではなく) なんだよ。
つまり送出される例外オブジェクトの型はわかっている。
むしろどこまで巻き戻せばよいか (送出されるオブジェクトの型に対応する catch はどこにあるか) の情報が動的なものだ。
2022/10/16(日) 14:48:55.82ID:pwk0SnpM
メンバ変数をまったく使っていないメンバ関数を見つける方法ってなんかある?
CppCheckとかでできるんだっけ
2022/10/16(日) 15:16:25.24ID:r52/9r+u
まあ普通の静的解析はチェックしてくれるのでは
2022/10/16(日) 17:18:37.82ID:Y43orZLw
>>876
typeidは仮想関数を持っているクラスにしか働かないと思っていたが、
働くのか。
2022/10/16(日) 17:21:15.08ID:Y43orZLw
typeid(x)の返すオブジェクトは完全にtype_info型なのか、
それとも、type_infoを継承したクラスなのか、どっち?
2022/10/16(日) 22:40:17.52ID:SvF0Fhwf
>>881
std::type_info から派生したクラスであることはあり得る。
https://timsong-cpp.github.io/cppwp/n3337/expr.typeid#1
2022/10/17(月) 05:46:15.36ID:SQKgR2D+
それこそtypeidに聞いてみりゃいい
cout << typeid(typeid(some_one)).name();
2022/10/17(月) 22:30:57.72ID:K/vFJtXQ
T x;
T y;
に対して
x=move(y); //(1)
とした場合、時系列的に
1. move代入演算子 T::operator=(T &&a);がyの中身をxに入れる。但しこれは、2とも
 関連しているがswap(x,y)とされることもある。
 swap(x,y)を使わない場合には、xにyの中身を入れる前に元々の xの中身が削除される。
2. swapを使って無い場合には、続いてmove代入演算子 T::operator=(T &&a);が
 y のポインタメンバなどに null 値を書き込む。
3. (1)の式の最後で、右辺のオブジェクト y に対してデストラクタが呼び出される。
4. デストラクタは、y ポインタメンバが null だと何も行なわない。
 yの中身がxに交換されていた場合は、もともとxの中身だったものを削除する。

というような流れになるという理解で合ってる?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。