C++相談室 part159at TECH
C++相談室 part159 - 暇つぶし2ch950:デフォルトの名無しさん
22/04/11 16:44:48 bKclHLZw.net
>>930 >>934
staticおにいさん「class外、*.cppにstatic修飾して書く」

951:デフォルトの名無しさん
22/04/11 19:36:19.35 KtON6/oU.net
>>935
昨年末あたりにvisual studioで試したらどうやってもビルド通らなくて諦めたけど今もう使えるようになってるんかな

952:デフォルトの名無しさん
22/04/12 01:31:53 EgjH8LRN.net
実験した程度でしかないけど使えてたよ。

953:デフォルトの名無しさん
22/04/12 10:13:21.46 5vVn8Fqf.net
>>934
その翻訳単位がグローバル領域だったら? って意味でしょ

954:はちみつ餃子
22/04/12 11:04:00.65 5njWaFr4.net
>>939
言いたいことがわからない。

955:デフォルトの名無しさん
22/04/12 16:43:20.82 qoqTD/fb.net
dfs とか bfs みたいな名前の関数はそれを呼ぶ関数とまとめたくなるよね分かる
関数内関数にすると他の関数から呼べなくなるしな
名前を変えよってのはナシなw

956:デフォルトの名無しさん
22/04/12 17:25:13.49 nzV1CUkS.net
モジュール……

957:デフォルトの名無しさん
22/04/12 17:51:32.45 RKLCiqJK.net
アホな質問かもしれないのですが……
今までユニークポインタで実体領域確保していたクラスを、どうせ一つしかnewしないからと、クラス内部に自身型の静的変数を保持して使用する方法へと変更しました。
所謂シングルトンに似た感じのものだと思うのですが。
std::unique-ptr<Hoge>Temp=std::make-unique<Hoge>();

static Hoge& GetInstance(){static Hoge temp;return temp;}
使用する分には問題ないのですが、実体化させたいクラス数が多く、結果的には静的変数のガズが増え、実体がグローバルに多数存在する状態になってしまっていると思います。
この場合、名前衝突以外に何か想定される不具合はありますか?
データを保持させるクラス以外は全てこれに置き換えようと思っているのですが、今までnewして使っていたため何か罠があると思えてなりません。
この方法はクラス名から実態を呼び出せて私に大変便利です。

958:デフォルトの名無しさん
22/04/12 18:22:24.95 fdFUG1QI.net
>>943
ないです

959:蟻人間
22/04/12 18:27:41.73 Dt0TGPDO.net
>>943
マルチスレッドじゃないよな

960:デフォルトの名無しさん
22/04/12 18:29:33.15 RKLCiqJK.net
>>944
ありがとうございます!
>>945
違います!
無さそうで安心でした

961:デフォルトの名無しさん
22/04/12 18:39:03.10 FTlcB8DO.net
クラス外側でtemplate実装にしろよとは思うが
template<class T>
inline T Instance;
int main(){
Instance<Hoge>.Execute();
}

962:デフォルトの名無しさん
22/04/12 19:21:11.76 72/2frZ9.net
static ローカル変数が定石じゃないの?

963:デフォルトの名無しさん
22/04/12 20:27:31.77 vgUv52EM.net
は?

964:デフォルトの名無しさん
22/04/12 20:30:19.09 X1V1J1VK.net
経験的にはどうせ静的なら変に隠さずグローバル変数の方が使いやすいです

965:デフォルトの名無しさん
22/04/12 21:36:16.25 RKLCiqJK.net
ちょっと皆さんの言ってることがよくわからないのですが……
テンプレートにして有効範囲で使用する、グローバルでいつでも呼び出せるようにする
ということでしょうか?
使用を想定しているのは膨大なデータのコンプレックスではなく、外部データ加工用に少量のローカル変数を持たせたクラスなので、実体はひつとで大丈夫だと思います。
その際には、衝突を考えないならば、グローバウに無造作に置いた方が使いやすいよ、ということでしょうか?

966:デフォルトの名無しさん
22/04/12 22:13:59.90 oNokQpOT.net
左再帰が無限ループになる理由を教えて

967:蟻人間
22/04/12 23:03:12.33 Dt0TGPDO.net
>>952
実引数と戻り先アドレスをスタックに繰り返し積むから。

968:蟻人間
22/04/12 23:31


969::14.39 ID:Dt0TGPDO.net



970:デフォルトの名無しさん
22/04/12 23:39:21.85 EarvAF13.net
停止しないから無限ループする
…って酷い理由だな

971:デフォルトの名無しさん
22/04/13 00:21:12.99 bubjF7cO.net
じゃあ停止するかどうかを判定する汎用ルーチンHを作ればいいんだよ。

972:947
22/04/13 01:25:51.41 qfz8Xp88.net
>>951
シングルトンを確保しておくためだけにstatic関数が10も20も並ぶのがアホくさいじゃん?
template 1つだけ書いておこうよって意図で書いた。
が、>>951 のように一時変数として使うならローカル変数にして使い捨てるべき。
グローバル変数(>>943 もやってることは同じ)を使うデメリットは調べればすぐ出てくる

973:デフォルトの名無しさん
22/04/13 05:51:58.22 8pcHyiAe.net
staticにインスタンス入れるやり方だとマルチスレッドマルチプロセスにした時すぐ破綻するから大き目の定数入れる以外には使ってないな

974:デフォルトの名無しさん
22/04/13 08:11:33 ZQqXT36F.net
グローバル変数は初期化順序が環境依存になる問題があるから、
呼び出し順序で初期化するインライン関数のstaticローカル変数の方が扱いやすい
という話があったかと思うけど、最近は回避するテクニックできたの?

975:デフォルトの名無しさん
22/04/13 09:44:11 abmOAw0D.net
>>959
それでも競合は起きうるよね
排他制御は必須

976:デフォルトの名無しさん
22/04/13 10:25:01.35 2DJG1h+b.net
相談
抽象的なノードクラスがあり、上流ノードから下流ノードが接続され情報を取り出したいとする
この時、接続時に上流ノードの出力タイプと、下流ノードの入力タイプが符合するかどうかを調べたい
今考えている実装方法としてenum型でタイプを列挙しておき、ノードの出力属性としてもたせ
入力に必要な属性を接続時に調べておく方法
シンプルでベストかなとは思うが、タイプが増えていくとその管理がやや大変かと思う
文字列で符合させるやり方も考えたが、例えば"int"と"integer"とかでごちゃごちゃしそう
なにか妙案があればお聞かせ願いたい

977:デフォルトの名無しさん
22/04/13 10:28:21.90 CyvaZh5F.net
抽象的でわからん

978:デフォルトの名無しさん
22/04/13 10:36:53.86 2DJG1h+b.net
すいません、もうちょっと自分で考えて相談点まとめます

979:デフォルトの名無しさん
22/04/13 10:44:17.47 zii+x7Ds.net
それぞれのスレッドでは個別だけど スレッド内では唯一のインスタンス
スレッドをまたいでも共通で唯一のインスタンス
あたまがこんらんする

980:デフォルトの名無しさん
22/04/13 12:06:05.65 IuPW2iUE.net
>>961
どのみち符号の管理・徹底は必須だから、文字列で符号化し、表とかにまとめてバージョン管理・周知徹底する。
protocol bufferとかでインターフェイス管理すれば少しは楽かね。
protocol buffer以外だとなにがいいかしらん?

981:デフォルトの名無しさん
22/04/13 12:12:18.93 5KnL277L.net
// 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);
}

982:蟻人間
22/04/13 12:20:05.74 +YltrYoo.net
std::vector<Foo*>
std::vector<Foo>
のインターフェイスに共通部分がない。アキラメロン。

983:947
22/04/13 13:02:01 sgl3F80B.net
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();

984:はちみつ餃子
22/04/13 13:12:01.75 qCcEdGhE.net
>>965
URLリンク(kaitai.io)

985:デフォルトの名無しさん
22/04/13 18:00:26 m7JtDTD6.net
>>957
今実機で確認して、インライン化したテンプレートをヘッダーに咥える方法が自分にとって良い事を確認しました!
ありがとうございます。
いちいちスタティック咥えるより良いと思います。

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

皆さんありがとうございます!

986:デフォルトの名無しさん
22/04/13 18:15:56.73 I4ieD//T.net
>>966
std::for_each(vf.begin(),vf.end(),std::mem_fn(&Foo::Func));
または
for (auto &&x : vf) { std::invoke(&Foo::Func, x); }

987:デフォルトの名無しさん
22/04/13 18:28:24 U0E88zpG.net
オマンコハンター チンポマン!
股間の銃を携えて今日もおまんこ狙い撃ち

988:デフォルトの名無しさん
22/04/13 23:40:49.30 grUsXYkY.net
>>971
ラムダが消されてて笑った

989:デフォルトの名無しさん
22/04/13 23:53:02.59 nvVh9cdQ.net
>>967

スキル低っ

990:デフォルトの名無しさん
22/04/14 07:29:49.75 Qd4x1CZh.net
シングルトンは要らない子、とヴァカにしていたが
グローバルなオブジェクトのコンストラの呼び出し順序が翻訳単位を超えた呼び出し順序がまるきり不
定になるというC/C++の仕様を回避するのには有効おと1 mgぐらい考えを新ためた
OSのwrapperを書いて、main()でそれを初期化することにして
グローバルなオブジェクトのコンストラから思わずOSのwrapper経由でログを吐かせようとしたらクラッシュして気づいたから
最初のOSのwrapperの最初の呼び出しでまだ未呼び出しなら初期化したら良い(ビコーン  ← まんまシングルトン
main()で初期化することが保証しているから、グローバルなコンストラの中でいきなりスレッドを起こしてそこから
OSのwrapperを呼ぶ、みたいなktgi行為が無い限りこのシングルトンはマルチスレッドの対策が不要
 

991:デフォルトの名無しさん
22/04/14 07:33:43.77 Qd4x1CZh.net
訂正orz、
誤: 最初のOSのwrapperの最初の呼び出しでまだ未呼び出しなら初期化したら良い(ビコーン  ← まんまシングルトン
正: 最初のOSのwrapperの最初の呼び出しでまだ未初期化なら初期化したら良い(ビコーン  ← まんまシングルトン

992:デフォルトの名無しさん
22/04/14 08:28:49 79II+WyL.net
別にシングルトンじゃなくても単に起動時に初期化して渡せばええやん

993:デフォルトの名無しさん
22/04/14 09:59:18.13 wwxSZsaE.net
いや要るでしょシングルトン
何らかのリソースマネージャ作るときとか避けて通れないし

994:デフォルトの名無しさん
22/04/14 10:35:30.42 dlHUY+WK.net
>>977
初期化順序の問題って回避できたっけ?

995:デフォルトの名無しさん
22/04/14 10:40:07.14 79II+WyL.net
mainでリソース用意しろという話よ
ライブラリだったら初期化用になんか叩いてもらえ

996:デフォルトの名無しさん
22/04/14 10:47:06 rsrkTEkU.net
グローバル変数をポインタにしておいてmainでnewとか
friend int main(int, char**); とか?

997:デフォルトの名無しさん
22/04/14 10:56:36 79II+WyL.net
なんでグローバル変数にこだわるんだよ

998:デフォルトの名無しさん
22/04/14 10:58:53 dlHUY+WK.net
>>980
シングルトンより制限多くてメリット感じないなぁ。
マキャベリスト対策は難しいかもしれないけど、マーフィーに呪われないように運用で回避するのは最後の手段にすべき。

999:デフォルトの名無しさん
22/04/14 15:09:30.09 4tVKG4Xu.net
1個でもグローバルなりがあると
エントリポイントの main よりも前に走るコンストラクタ内部であれこれされる可能性を想定する必要に迫られる と

1000:デフォルトの名無しさん
22/04/15 00:01:53.91 he9C7sX7.net
>>981
> グローバル変数をポインタにしておいてmainでnewとか
> friend int main(int, char**); とか?
それは最初にやったがブ


1001:ツがOSのwrapperなのでカッコワルダサいと思い考え直した 結果がマルチスレッド対応を含まないライトなシングルトンの適用 >>980 main()に入ってから初期化するというだけでは初期化が間に合わないケースがあるから何とかしたいという話



1002:デフォルトの名無しさん
22/04/15 00:06:58.93 xDiQzMrD.net
mainの実行より前に意味があることしようと思ったらコンパイル時しかなかろうよ

1003:デフォルトの名無しさん
22/04/15 00:13:00.39 he9C7sX7.net
>>986の主観の話をしているのではない件について:

1004:デフォルトの名無しさん
22/04/15 00:22:10.66 xDiQzMrD.net
>>987
お前のグローバル変数愛は主観じゃないんかいな
もっと崇高な何かがあるのか

1005:デフォルトの名無しさん
22/04/15 04:08:04.71 sm6VHVYM.net
静的ストレージは実装と心中するプログラム以外マジでやめといたほうがいい
移植性が大幅に低下する

1006:デフォルトの名無しさん
22/04/15 04:23:41.78 1Y3hD0GJ.net
グローバルやstaticな変数を使用する時は排他制御を必ず行なう
これを厳守していれば使っても大丈夫です
もちろん使わずに済む別の方法がある時は別の方法を取るべきです

1007:デフォルトの名無しさん
22/04/15 06:36:24.15 he9C7sX7.net
>>988
・任意のユーザーが任意のクラスをグローバル変数として使うことをOSが禁止するわけにはいかない
・クラスのコンストラクタでOS資源を確保することは普通(イベントオブジェクトを確保する等、ハンドルのメンバを有効な値で初期化しようとする
・誰かがグローバル変数のコンストラクタでOSの資源を確保しようとしたら、この場合初期化前のOSのwrapperが呼ばれる
ここまで書かないと>>986がいかにたわごとを言っているかわからないわけ?!
>>990
>グローバルやstaticな変数を使用する時は排他制御を必ず行なう
まあそれはそう。今回排他制御を避けられるのは
>main()で初期化することが保証しているから、グローバルなコンストラの中でいきなりスレッドを起こしてそこから
>OSのwrapperを呼ぶ、みたいなktgi行為が無い限りこのシングルトンはマルチスレッドの対策が不要
というktgi行為が無いことの条件付き。

1008:デフォルトの名無しさん
22/04/15 07:35:15 xDiQzMrD.net
>>991
えっと、つまり、使えるものは使わずにはおれない一族に生まれたということですか?

1009:デフォルトの名無しさん
22/04/15 08:15:20.73 xhqbcuaF.net
>>991
c++11から静的ローカル変数の初期化は自動的に排他制御され、スレッドセーフとなる[10]。 だって。
シングルトンパターンの何を問題視しているんだっけ?

1010:デフォルトの名無しさん
22/04/15 08:29:52.88 y04/Kx9U.net
自分で記述するだけならどうとでもなるけど
他人に使ってもらう前提だと
限度はあるにしても色々防護策を講じたくなるのもわかる

1011:デフォルトの名無しさん
22/04/15 08:31:14.00 xDiQzMrD.net
モジュールの結合度を評価するのにまず排他がどうとか気にするもんかね?

1012:デフォルトの名無しさん
22/04/15 08:40:46.42 WMzvufu2.net
C++相談室 part160
スレリンク(tech板)

1013:デフォルトの名無しさん
22/04/15 08:43:44.23 ZcCJtqdn.net
>>995
それとは独立の問題
並行&並列でも動くことが現代では求められているため
一般的にグローバルやstatic変数の読み書きには排他制御が必ず必要となる
厳密な意味で変数ではなく一度限り初期化される定数のようなものの場合はその初期化が排他制御される保証のみでも大丈夫なだけ

1014:デフォルトの名無しさん
22/04/15 08:44:18.42 wykOop5a.net
>>994
シングルトンパターンならコンストラクタをプライベートにするんだから、そもそもグローバル変数として初期化できないんじゃない?

1015:デフォルトの名無しさん
22/04/15 08:44:58.60 wykOop5a.net
>>997
>>993

1016:デフォルトの名無しさん
22/04/15 08:49:06.65 xDiQzMrD.net
>>997
グローバル変数批判でまずそれが問題だと思うのはどうかしてるよ

1017:1001
Over 1000 Thread.net
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 54日 20時間 52分 24秒

1018:過去ログ ★
[過去ログ]
■ このスレッドは過去ログ倉庫に格納されています


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch