C++相談室 part159

レス数が1000を超えています。これ以上書き込みはできません。
1デフォルトの名無しさん
垢版 |
2022/02/19(土) 11:56:42.14ID:kSnJ/KwP
前スレ
C++相談室 part158
https://mevius.5ch.net/test/read.cgi/tech/1636969758/
2022/04/09(土) 22:53:29.39ID:NDf9sYGT
出てくるわけねーじゃん
バカですか?
2022/04/09(土) 23:32:57.29ID:lfgNvR7s
std::threadで作ったスレッドのスタックサイズは1 MBで
変更はできないら
しい

今日日は仮想メモリがあるからなリ
ッチなマシンなら……
2022/04/10(日) 01:07:52.01ID:OW76vhVn
標準ライブラリなんて普通使わないだろ
汎用的にしすぎてて、いらない機能が多いからやたらと遅いし
2022/04/10(日) 01:48:34.97ID:vpYyJyBE
標準以外なにをつかうんだ
2022/04/10(日) 04:47:34.93ID:Fso6oKAR
_beginthreadex()
2022/04/10(日) 05:15:04.39ID:RmTwSS8K
pthread
924デフォルトの名無しさん
垢版 |
2022/04/10(日) 05:58:59.81ID:xcZwEbFY
<thread>で抽象化されていないOS特有の機能を使いたきゃAPI使うってだけ
2022/04/10(日) 11:29:27.51ID:lpHEMRFm
>>921
大抵は自社でフレームワーク構築してるよ
iostreamですら、includeしたプルリク蹴らられるし
2022/04/10(日) 11:37:41.44ID:vpYyJyBE
>>925
被せるだけじゃなくて自作すんの?
2022/04/10(日) 11:57:59.43ID:Np98oj9K
ちんちんシュッ!シュッ!シュッ!
2022/04/10(日) 13:14:21.25ID:wqaUV7TG
>>921
OSのAPI直で叩けってことやろ
例えばCreateThreadならスタックサイズ指定できるし
2022/04/10(日) 16:50:49.57ID:8UzTPUX4
>>925
うちもstringとかコンテナクラスは全部自作してる
昔はプラットフォームがUNIXもあったりして、環境によってはSTL使うと
コンパイルエラーになってたからな
2022/04/11(月) 06:43:40.41ID:x3kzaSAd
関数群をまとめたいときってクラスで切るべき? 名前空間で切るべき?
例えば sub1、 sub2 というサブルーチンがあって、これらが func1、func2 から呼ばれるときに、これらをまとめたいと思うんです
931デフォルトの名無しさん
垢版 |
2022/04/11(月) 06:51:36.36ID:r64ZejsB
べきという言い方はあまり好まんが

関数間で連携させるならクラス
連携しない単なるグループなら名前空間
というのが俺がよく使う手だ
2022/04/11(月) 06:54:00.91ID:sjzgKw67
> これらをまとめたいと思うんです
どうまとめたいんだよ…
2022/04/11(月) 12:12:27.70ID:sxIacEU4
mc++d読んだけど、これが20年前以上に書かれたってことがすごいな
今となっては、当たり前のことをばっかだけど
当時は革新的だったんじゃないかな
2022/04/11(月) 13:01:51.57ID:7nQKgh0L
>>930
特定の範囲でしか使わない関数があるという意味?
それだけの理由なら名前空間でもクラスでも分ける必要はない。
その翻訳単位で内部リンケージにしておけば十分だよ。

名前空間やクラスは外部に対してどう見せるかの問題なんだから
機能単位の中で階層を分ける必要はあんまりない。
2022/04/11(月) 15:33:36.87ID:gXppguDy
そういや翻訳単位の管理として新しくモジュールがc++20から導入されたけど、使い心地どうかしらん?
既存コードもモジュール化した方がいいくらい便利だったりするのかしらん?
2022/04/11(月) 16:44:48.15ID:bKclHLZw
>>930 >>934
staticおにいさん「class外、*.cppにstatic修飾して書く」
2022/04/11(月) 19:36:19.35ID:KtON6/oU
>>935
昨年末あたりにvisual studioで試したらどうやってもビルド通らなくて諦めたけど今もう使えるようになってるんかな
2022/04/12(火) 01:31:53.93ID:EgjH8LRN
実験した程度でしかないけど使えてたよ。
2022/04/12(火) 10:13:21.46ID:5vVn8Fqf
>>934
その翻訳単位がグローバル領域だったら? って意味でしょ
2022/04/12(火) 11:04:00.65ID:5njWaFr4
>>939
言いたいことがわからない。
2022/04/12(火) 16:43:20.82ID:qoqTD/fb
dfs とか bfs みたいな名前の関数はそれを呼ぶ関数とまとめたくなるよね分かる
関数内関数にすると他の関数から呼べなくなるしな

名前を変えよってのはナシなw
2022/04/12(火) 17:25:13.49ID:nzV1CUkS
モジュール……
943デフォルトの名無しさん
垢版 |
2022/04/12(火) 17:51:32.45ID:RKLCiqJK
アホな質問かもしれないのですが……
今までユニークポインタで実体領域確保していたクラスを、どうせ一つしかnewしないからと、クラス内部に自身型の静的変数を保持して使用する方法へと変更しました。
所謂シングルトンに似た感じのものだと思うのですが。

std::unique-ptr<Hoge>Temp=std::make-unique<Hoge>();

static Hoge& GetInstance(){static Hoge temp;return temp;}

使用する分には問題ないのですが、実体化させたいクラス数が多く、結果的には静的変数のガズが増え、実体がグローバルに多数存在する状態になってしまっていると思います。
この場合、名前衝突以外に何か想定される不具合はありますか?
データを保持させるクラス以外は全てこれに置き換えようと思っているのですが、今までnewして使っていたため何か罠があると思えてなりません。
この方法はクラス名から実態を呼び出せて私に大変便利です。
2022/04/12(火) 18:22:24.95ID:fdFUG1QI
>>943
ないです
2022/04/12(火) 18:27:41.73ID:Dt0TGPDO
>>943
マルチスレッドじゃないよな
946デフォルトの名無しさん
垢版 |
2022/04/12(火) 18:29:33.15ID:RKLCiqJK
>>944
ありがとうございます!
>>945
違います!

無さそうで安心でした
2022/04/12(火) 18:39:03.10ID:FTlcB8DO
クラス外側でtemplate実装にしろよとは思うが

template<class T>
inline T Instance;

int main(){
Instance<Hoge>.Execute();
}
2022/04/12(火) 19:21:11.76ID:72/2frZ9
static ローカル変数が定石じゃないの?
2022/04/12(火) 20:27:31.77ID:vgUv52EM
は?
2022/04/12(火) 20:30:19.09ID:X1V1J1VK
経験的にはどうせ静的なら変に隠さずグローバル変数の方が使いやすいです
951デフォルトの名無しさん
垢版 |
2022/04/12(火) 21:36:16.25ID:RKLCiqJK
ちょっと皆さんの言ってることがよくわからないのですが……
テンプレートにして有効範囲で使用する、グローバルでいつでも呼び出せるようにする
ということでしょうか?
使用を想定しているのは膨大なデータのコンプレックスではなく、外部データ加工用に少量のローカル変数を持たせたクラスなので、実体はひつとで大丈夫だと思います。
その際には、衝突を考えないならば、グローバウに無造作に置いた方が使いやすいよ、ということでしょうか?
2022/04/12(火) 22:13:59.90ID:oNokQpOT
左再帰が無限ループになる理由を教えて
2022/04/12(火) 23:03:12.33ID:Dt0TGPDO
>>952
実引数と戻り先アドレスをスタックに繰り返し積むから。
2022/04/12(火) 23:31:14.39ID:Dt0TGPDO
積んで解放しないから。
2022/04/12(火) 23:39:21.85ID:EarvAF13
停止しないから無限ループする
…って酷い理由だな
2022/04/13(水) 00:21:12.99ID:bubjF7cO
じゃあ停止するかどうかを判定する汎用ルーチンHを作ればいいんだよ。
957947
垢版 |
2022/04/13(水) 01:25:51.41ID:qfz8Xp88
>>951
シングルトンを確保しておくためだけにstatic関数が10も20も並ぶのがアホくさいじゃん?
template 1つだけ書いておこうよって意図で書いた。

が、>>951 のように一時変数として使うならローカル変数にして使い捨てるべき。

グローバル変数(>>943 もやってることは同じ)を使うデメリットは調べればすぐ出てくる
2022/04/13(水) 05:51:58.22ID:8pcHyiAe
staticにインスタンス入れるやり方だとマルチスレッドマルチプロセスにした時すぐ破綻するから大き目の定数入れる以外には使ってないな
2022/04/13(水) 08:11:33.40ID:ZQqXT36F
グローバル変数は初期化順序が環境依存になる問題があるから、
呼び出し順序で初期化するインライン関数のstaticローカル変数の方が扱いやすい
という話があったかと思うけど、最近は回避するテクニックできたの?
2022/04/13(水) 09:44:11.11ID:abmOAw0D
>>959
それでも競合は起きうるよね
排他制御は必須
2022/04/13(水) 10:25:01.35ID:2DJG1h+b
相談
抽象的なノードクラスがあり、上流ノードから下流ノードが接続され情報を取り出したいとする
この時、接続時に上流ノードの出力タイプと、下流ノードの入力タイプが符合するかどうかを調べたい
今考えている実装方法としてenum型でタイプを列挙しておき、ノードの出力属性としてもたせ
入力に必要な属性を接続時に調べておく方法
シンプルでベストかなとは思うが、タイプが増えていくとその管理がやや大変かと思う
文字列で符合させるやり方も考えたが、例えば"int"と"integer"とかでごちゃごちゃしそう
なにか妙案があればお聞かせ願いたい
2022/04/13(水) 10:28:21.90ID:CyvaZh5F
抽象的でわからん
2022/04/13(水) 10:36:53.86ID:2DJG1h+b
すいません、もうちょっと自分で考えて相談点まとめます
2022/04/13(水) 10:44:17.47ID:zii+x7Ds
それぞれのスレッドでは個別だけど スレッド内では唯一のインスタンス
スレッドをまたいでも共通で唯一のインスタンス
あたまがこんらんする
2022/04/13(水) 12:06:05.65ID:IuPW2iUE
>>961
どのみち符号の管理・徹底は必須だから、文字列で符号化し、表とかにまとめてバージョン管理・周知徹底する。

protocol bufferとかでインターフェイス管理すれば少しは楽かね。
protocol buffer以外だとなにがいいかしらん?
2022/04/13(水) 12:12:18.93ID:5KnL277L
// A と Bのところだけが異なるfとf2
// うまくこの関数をまとめれませんか?

#include <iostream>
#include <vector>
#include <algorithm>

struct Foo
{
void Func() const
{}
};

void f(const std::vector<Foo>& vf)
{
std::for_each(vf.begin(),vf.end(),
[](auto&& f)
{
f.Func();//A
}
);
}

void f2(const std::vector<Foo*>& vf)
{
std::for_each(vf.begin(),vf.end(),
[](auto&& f)
{
f->Func();//B
}
);
}

int main( int argc, char *argv[] )
{
std::vector<Foo> vf;
std::vector<Foo*> vfp;

 f(vf);
 f2(vfp);
}
2022/04/13(水) 12:20:05.74ID:+YltrYoo
std::vector<Foo*>
std::vector<Foo>
のインターフェイスに共通部分がない。アキラメロン。
968947
垢版 |
2022/04/13(水) 13:02:01.63ID:sgl3F80B
type_traitsで殴ればいけそう

template<class T>
auto& to_reference_if_pointer(T&t){
if constexpr(std::is_pointer_v<T>){
return *t;
}else{
return t;
}
}


to_reference_if_pointer(f).Func();
2022/04/13(水) 13:12:01.75ID:qCcEdGhE
>>965
https://kaitai.io/
970デフォルトの名無しさん
垢版 |
2022/04/13(水) 18:00:26.46ID:m7JtDTD6
>>957
今実機で確認して、インライン化したテンプレートをヘッダーに咥える方法が自分にとって良い事を確認しました!
ありがとうございます。
いちいちスタティック咥えるより良いと思います。

マルチスレッドは使用したことがないのでわかりませんが、なるべき勉強してみたいと思います。

皆さんありがとうございます!
2022/04/13(水) 18:15:56.73ID:I4ieD//T
>>966
std::for_each(vf.begin(),vf.end(),std::mem_fn(&Foo::Func));
または
for (auto &&x : vf) { std::invoke(&Foo::Func, x); }
972デフォルトの名無しさん
垢版 |
2022/04/13(水) 18:28:24.44ID:U0E88zpG
オマンコハンター チンポマン!
股間の銃を携えて今日もおまんこ狙い撃ち
2022/04/13(水) 23:40:49.30ID:grUsXYkY
>>971
ラムダが消されてて笑った
2022/04/13(水) 23:53:02.59ID:nvVh9cdQ
>>967

スキル低っ
2022/04/14(木) 07:29:49.75ID:Qd4x1CZh
シングルトンは要らない子、とヴァカにしていたが
グローバルなオブジェクトのコンストラの呼び出し順序が翻訳単位を超えた呼び出し順序がまるきり不
定になるというC/C++の仕様を回避するのには有効おと1 mgぐらい考えを新ためた
OSのwrapperを書いて、main()でそれを初期化することにして
グローバルなオブジェクトのコンストラから思わずOSのwrapper経由でログを吐かせようとしたらクラッシュして気づいたから
最初のOSのwrapperの最初の呼び出しでまだ未呼び出しなら初期化したら良い(ビコーン  ← まんまシングルトン

main()で初期化することが保証しているから、グローバルなコンストラの中でいきなりスレッドを起こしてそこから
OSのwrapperを呼ぶ、みたいなktgi行為が無い限りこのシングルトンはマルチスレッドの対策が不要
 
2022/04/14(木) 07:33:43.77ID:Qd4x1CZh
訂正orz、
誤: 最初のOSのwrapperの最初の呼び出しでまだ未呼び出しなら初期化したら良い(ビコーン  ← まんまシングルトン
正: 最初のOSのwrapperの最初の呼び出しでまだ未初期化なら初期化したら良い(ビコーン  ← まんまシングルトン
2022/04/14(木) 08:28:49.07ID:79II+WyL
別にシングルトンじゃなくても単に起動時に初期化して渡せばええやん
2022/04/14(木) 09:59:18.13ID:wwxSZsaE
いや要るでしょシングルトン
何らかのリソースマネージャ作るときとか避けて通れないし
2022/04/14(木) 10:35:30.42ID:dlHUY+WK
>>977
初期化順序の問題って回避できたっけ?
2022/04/14(木) 10:40:07.14ID:79II+WyL
mainでリソース用意しろという話よ
ライブラリだったら初期化用になんか叩いてもらえ
2022/04/14(木) 10:47:06.20ID:rsrkTEkU
グローバル変数をポインタにしておいてmainでnewとか
friend int main(int, char**); とか?
2022/04/14(木) 10:56:36.07ID:79II+WyL
なんでグローバル変数にこだわるんだよ
2022/04/14(木) 10:58:53.82ID:dlHUY+WK
>>980
シングルトンより制限多くてメリット感じないなぁ。
マキャベリスト対策は難しいかもしれないけど、マーフィーに呪われないように運用で回避するのは最後の手段にすべき。
2022/04/14(木) 15:09:30.09ID:4tVKG4Xu
1個でもグローバルなりがあると
エントリポイントの main よりも前に走るコンストラクタ内部であれこれされる可能性を想定する必要に迫られる と
2022/04/15(金) 00:01:53.91ID:he9C7sX7
>>981
> グローバル変数をポインタにしておいてmainでnewとか
> friend int main(int, char**); とか?
それは最初にやったがブツがOSのwrapperなのでカッコワルダサいと思い考え直した
結果がマルチスレッド対応を含まないライトなシングルトンの適用

>>980
main()に入ってから初期化するというだけでは初期化が間に合わないケースがあるから何とかしたいという話
2022/04/15(金) 00:06:58.93ID:xDiQzMrD
mainの実行より前に意味があることしようと思ったらコンパイル時しかなかろうよ
2022/04/15(金) 00:13:00.39ID:he9C7sX7
>>986の主観の話をしているのではない件について:
2022/04/15(金) 00:22:10.66ID:xDiQzMrD
>>987
お前のグローバル変数愛は主観じゃないんかいな
もっと崇高な何かがあるのか
2022/04/15(金) 04:08:04.71ID:sm6VHVYM
静的ストレージは実装と心中するプログラム以外マジでやめといたほうがいい
移植性が大幅に低下する
2022/04/15(金) 04:23:41.78ID:1Y3hD0GJ
グローバルやstaticな変数を使用する時は排他制御を必ず行なう
これを厳守していれば使っても大丈夫です
もちろん使わずに済む別の方法がある時は別の方法を取るべきです
2022/04/15(金) 06:36:24.15ID:he9C7sX7
>>988
・任意のユーザーが任意のクラスをグローバル変数として使うことをOSが禁止するわけにはいかない
・クラスのコンストラクタでOS資源を確保することは普通(イベントオブジェクトを確保する等、ハンドルのメンバを有効な値で初期化しようとする
・誰かがグローバル変数のコンストラクタでOSの資源を確保しようとしたら、この場合初期化前のOSのwrapperが呼ばれる
ここまで書かないと>>986がいかにたわごとを言っているかわからないわけ?!

>>990
>グローバルやstaticな変数を使用する時は排他制御を必ず行なう
まあそれはそう。今回排他制御を避けられるのは
>main()で初期化することが保証しているから、グローバルなコンストラの中でいきなりスレッドを起こしてそこから
>OSのwrapperを呼ぶ、みたいなktgi行為が無い限りこのシングルトンはマルチスレッドの対策が不要
というktgi行為が無いことの条件付き。
2022/04/15(金) 07:35:15.38ID:xDiQzMrD
>>991
えっと、つまり、使えるものは使わずにはおれない一族に生まれたということですか?
2022/04/15(金) 08:15:20.73ID:xhqbcuaF
>>991
c++11から静的ローカル変数の初期化は自動的に排他制御され、スレッドセーフとなる[10]。 だって。
シングルトンパターンの何を問題視しているんだっけ?
2022/04/15(金) 08:29:52.88ID:y04/Kx9U
自分で記述するだけならどうとでもなるけど
他人に使ってもらう前提だと
限度はあるにしても色々防護策を講じたくなるのもわかる
2022/04/15(金) 08:31:14.00ID:xDiQzMrD
モジュールの結合度を評価するのにまず排他がどうとか気にするもんかね?
2022/04/15(金) 08:40:46.42ID:WMzvufu2
C++相談室 part160
https://mevius.5ch.net/test/read.cgi/tech/1649979572/
2022/04/15(金) 08:43:44.23ID:ZcCJtqdn
>>995
それとは独立の問題
並行&並列でも動くことが現代では求められているため
一般的にグローバルやstatic変数の読み書きには排他制御が必ず必要となる
厳密な意味で変数ではなく一度限り初期化される定数のようなものの場合はその初期化が排他制御される保証のみでも大丈夫なだけ
2022/04/15(金) 08:44:18.42ID:wykOop5a
>>994
シングルトンパターンならコンストラクタをプライベートにするんだから、そもそもグローバル変数として初期化できないんじゃない?
2022/04/15(金) 08:44:58.60ID:wykOop5a
>>997
>>993
2022/04/15(金) 08:49:06.65ID:xDiQzMrD
>>997
グローバル変数批判でまずそれが問題だと思うのはどうかしてるよ
10011001
垢版 |
Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 54日 20時間 52分 24秒
レス数が1000を超えています。これ以上書き込みはできません。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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