C++相談室 part157

■ このスレッドは過去ログ倉庫に格納されています
2021/08/09(月) 10:57:31.60ID:JaaB5Egp
前スレ
C++相談室 part156
https://mevius.5ch.net/test/read.cgi/tech/1621389313/
2021/09/26(日) 13:18:19.13ID:loHIOGgF
確かモルダーを疲れさせる女のこと
2021/09/26(日) 13:28:55.11ID:pztAGZv/
対象外
ぷりみ恥部とPOD以外だめ
2021/09/26(日) 14:59:44.58ID:4UIlewCz
>>438
std::complexはclass型だよ。c++では
2021/09/26(日) 15:02:24.84ID:9lvhFgGq
>>441
つまりatomicはプリミティブ型だけ想定してるってことですかね
ありがとうございます
おとなしくクリティカルセクションにします
2021/09/27(月) 00:54:20.59ID:vtQXnC4F
>>438
C++ におけるスカラ型の定義
・ 算術型 (整数型と浮動小数点数型)
・ 列挙型
・ ポインタ型
・ メンバへのポインタ型
・ std::nullptr_t
・ 以上を cv 修飾 (const や volatile で修飾) したもの

https://timsong-cpp.github.io/cppwp/n3337/basic.types#9

言語によって定義は異なっている (または定義を持たない) ので
コンピューター用語として一般化は出来ないと思う。
2021/09/27(月) 06:07:00.04ID:vzE92GBt
ここはC++スレだからC++用語で必要充分だ
無理に一般化する必要はない
2021/09/27(月) 08:56:19.98ID:P6ytpwfT
複素数が「算術型」じゃないのって冷静に考えるの結構奇妙だな
2021/09/27(月) 19:18:30.57ID:LR1S7vXs
複素数を直接扱う命令がないCPUが多い以上、小数2個で表される複素数がスカラではないのは自然だと思うけど

それを言い出すと、一般線形群と呼ばれる行列はなんでも算術型になるのではないか?と思えてくるし
2021/09/27(月) 19:25:38.25ID:n9hc+rIL
arithmeticを「算術」とか仰々しく訳すからおかしくなる
要は小学生がさんすうで習うような単純な数のことよ
2021/09/27(月) 22:16:24.75ID:D7AKGDxr
そもそも数学でも複素数はスカラじゃないよな
2021/09/27(月) 22:19:03.53ID:sGjfmd1K
ベクトルの係数になるんだから基本的にスカラじゃねえの
2021/09/27(月) 22:43:23.51ID:PI7czi9F
スカラーだったりベクトルだったりするらしい
http://izumi-math.jp/K_Manabe/what_v/what_v_3.htm
2021/09/27(月) 22:51:45.61ID:GPisoDJi
複素ベクトル空間の係数体の元として見ればスカラだし複素数体を実ベクトル空間と見れば複素数は実ベクトル
2021/09/28(火) 07:58:37.24ID:ZoUlFxaV
除算が定義できる体なので普通はスカラーとして扱うと思うけどな。
2要素の実ベクトルや2自由度の行列に適切な演算を導入することによって同一視することはできる。
453デフォルトの名無しさん
垢版 |
2021/09/29(水) 10:21:13.97ID:QYKzykPR
>>447
要は小学生がさんすうで習うような単純な数のことを「算術」と言うんだが
2021/09/29(水) 18:51:49.92ID:+NS+8RdU
>>452
>2自由度の行列に適切な演算を導入
有名な a b -b a 以外にも複素数と同様に振舞う行列を定義できるものでしょうか?それはどんな形?
2021/09/29(水) 19:37:07.20ID:F6bYTA4Q
好きなX^2=-Iを満たす行列Xを用意すればaI+bXが複素数の表現になるよ
2021/09/30(木) 04:33:42.15ID:a96KQdEj
>>454
> 有名な a b -b a 以外にも
> 複素数と同様に振舞う行列

この世のことを何一つとして理解してないことがよく伝わってくる2フレーズ
457デフォルトの名無しさん
垢版 |
2021/09/30(木) 10:27:42.19ID:rsDh5L5E
i 0
0 i
2021/09/30(木) 12:07:05.65ID:CrfxKotF
複素数z=x+iy (x, y:実数)とした場合どうやって行列で表現できるのか分からん
そもそも無理だろ
2021/09/30(木) 12:15:59.67ID:LH+TfD4u
いい加減スレチだぞお前ら
2021/09/30(木) 12:39:55.75ID:HqpdIwHE
複素数の実行列表現あたりで調べれば出てくるから自分で調べろ。

複素数ライブラリの実装は行列表現だろ。
2021/09/30(木) 14:36:41.46ID:rqtJMe+2
承認欲求が満たされなかったキチガイのハ◯ンが荒らしてるんだな
2021/09/30(木) 21:06:22.87ID:SS5VJirH
>>460
キーワードありがとうございます!
1, 1, -2, -1 とか 3, 2, -5, -3 とか i に対応するものはいろいろあるんですね

>>456
生きていてすみません
2021/09/30(木) 22:32:11.42ID:hyVGcxZ+
複素数ライブラリの実装が行列表現な訳ないだろ
464デフォルトの名無しさん
垢版 |
2021/10/01(金) 04:28:27.07ID:YSb3+a7i
パウリ行列やで
2021/10/01(金) 08:55:53.93ID:wyBR1P+Z
それは四元数では
2021/10/01(金) 11:45:26.96ID:o+E+DUKy
そもそも勝手な演算❎とかを用意して、それを複素数の演算になるような演算規則にすればいいだけの話

普通のプログラミング言語での実装は2要素ベクトルに対して複素数積となるような演算を*に対応させているんだと思うけどな

行列積が複素数の積と同一視できるような表現行列があるというだけ

群論とか環論とか体論とか入門的にでもやればわかるよ
2021/10/02(土) 13:55:46.16ID:cR/mfYmg
ベクトルの要素は座標変換で変わるからスカラーではない
2021/10/02(土) 13:59:33.99ID:cR/mfYmg
まつがえたorz
誤: 変わるから
正: 変化すっから
2021/10/02(土) 14:34:20.70ID:7v0dyN4q
物理屋さんか?
2021/10/02(土) 14:56:43.55ID:cR/mfYmg
んまーたしかに物理現象は座標変換しても変わらない(同じもの)とみなすのが
物理の先生なのかもしれん スカラーもそん延長線上の概念
しかし観測が系に影響を与えると言い出した時点でいつまで真理でありつづけることやら……
2021/10/02(土) 20:42:45.96ID:xJ5F1jwy
>>467
言葉足らずだったかもしれないが、複素数体と数学的にはR2の正規直交基底かつ基底の長さが1のベクトルの成分表示を、適切な演算を入れることによって同一視することができるという話をしているのであって、一般的なベクトル空間の話をしている訳ではない。
2021/10/02(土) 21:15:26.25ID:cR/mfYmg
スカラーか否かというのは数をどこに使うかの話であって
数をどう表現するかの話ではないし、
2021/10/02(土) 21:16:10.17ID:cR/mfYmg
それはそうとしてR^2と言っただけでは計量が入っていないから(平行移動も糞も無いため)ベクトル空間ではない
つまり { ベクトル空間 } ⊂ { R^2 } であってR^2の方がより一般的

R^2上で実数と同じ7つの演算則を満たす演算を形式的に定義することはできるが|i|=1を表すために
>正規直交基底かつ基底の長さが1のベクトルの成分表示
が必要になるから複素数体を正確に言い表すにはR^2ではなくてユークリッド空間か何かが要ることになるんじゃないの
2021/10/02(土) 22:42:32.17ID:5uoG6j9g
加法(V × V → V)と係数体による倍演算(K × V → V)が入ってて線型ならベクトル空間だよ, 計量入れたら計量ベクトル空間
2021/10/05(火) 17:00:23.30ID:YgA3J5wy
関数の引数に参照渡しで何も渡さないようにするはどうすればよいですか

自作クラスAがあったとして、それを引数にとる関数
void hoge(int& p1, A& p2)
があります。

ただ、p2は、ケースによっては要らない場合もあって、その場合にはどうすればよいですか。

調べてみたらnullptrみたいなのはあったので、
int p1 = 1;
hoge(p1, nullptr);
と書いてみても、
非constの左辺が何とかとエラーが出て、渡せませんでした。
2021/10/05(火) 17:34:05.28ID:lBT+65cn
*nullptr
2021/10/05(火) 17:41:01.80ID:krkmojOq
>>475
参照は何も参照していない状態というのは作れない。
参照で受け取るように書いてあればその参照が無効ということはあり得ないという表明として解釈するのが通例。
(実際にはダングリング参照はあり得るけどそれは単に間違ったプログラムなので気にしない。)

引数として不要なのであればオーバーロードで引数が不要な関数も用意するのが真っ当な方法だけれど、
どうしても無効ということを表す状態を渡したいということであればダミーのオブジェクトを作っておいて
それを無効の意味に使うという方法は考えられる。 (不格好だけど……。)

#include <iostream>

struct A {};
A dummy;

void hoge(int& p1, A& p2 = dummy) {
if(&dummy == &p2) std::cout << "p2 is dummy" << std::endl;
else std::cout << "p2 is not dummy" << std::endl;
}

int main(void) {
int foo = 1;
A bar;
hoge(foo, bar);
hoge(foo);
}

あるいは std::variant と std::monostate と std::ref を組み合わせれば表現できなくもないかなぁ……。
2021/10/05(火) 17:45:03.34ID:UD2fraRe
NullObjectパターンすね
2021/10/05(火) 17:48:18.95ID:lBT+65cn
hoge(p1,* static_cast<A*>(nullptr));
2021/10/05(火) 17:49:14.63ID:3jRalumJ
>>476
*(A *)nullptr にしないとエラーになるな
そいで関数側で&p2==nullptrでnullptrが渡されたかどうかチェックできるね
でもこんなの許されてるの?
2021/10/05(火) 17:52:23.11ID:krkmojOq
>>476 >>480
当然だけど (空ポインタを含めて) 無効なポインタをデリファレンスしたらその時点で未定義。
2021/10/05(火) 19:00:16.73ID:lBT+65cn
何いってんだ
キチンと動作する
ただの参照なんだから未定義じゃないだろ
他の変数に受け渡してるワケでもないし
2021/10/05(火) 19:59:32.04ID:krkmojOq
>>482
実質的な (コンパイルされた後の) 動作として値を取り出す必要がないというのは、
言語仕様上において * の適用を無かったことに出来るわけではない。
(C には単項 * の結果に単項 & を適用した場合に相殺されてどちらも無かったことになる規則があるが……。)
2021/10/05(火) 20:26:29.70ID:SwNxahaG
また未定義動作なんか怖くない君か
命知らずなのはいいけどチームプログラミングには関わらないでね本当に迷惑だから
2021/10/05(火) 20:32:26.64ID:7rL/DhC7
1. 参照をやめてポインタにする
2. std::optional<T>を使う(C++17以降)

俺ならこのどっちか
2021/10/05(火) 22:18:37.99ID:bhHmmGon
クラスTが自作クラスなら
Tにnulを意味するlオブジェクトを定義すれば良い……
>>477なdummyオブジェクト方式はテンプレートの中で使いにくくなるいはず
>>485なstd::optional<T>案はどうせ余計な記憶を要するのだからT固有のnullを定義するうのとイーブン
2021/10/05(火) 22:24:32.10ID:bhHmmGon
もちろんT固有のnull「値」の定義においては
  オブジェクトの参照 == null値、
はアドレスの一致ではなく値の一致として解釈されねばならな
2021/10/05(火) 22:44:53.78ID:bhHmmGon
さもないと、クラスTのnull値をT_NULLみたいな名前にしたとして、
  T arr[] = { T_NULL, T_NULL, T_NULL, T_NULL };
みたいなことができないか
らな
2021/10/06(水) 00:36:12.25ID:meWA0K5y
>>480,482
gcc 11 の -O2 で「&p2==nullptrでnullptrが渡されたかどうかチェック」はできなかった。
https://wandbox.org/permlink/c9QQIkFRPpFHd7rL
2021/10/06(水) 00:55:04.49ID:E9G/hK4q
void hoge(int& p1, optional<A>& p2 = nullopt) { // constじゃないのでエラー
みたいなことってoptionalで上手いことやる方法ないの?
呼び出し元は
int i;
A a;
hoge(i, a);
hoge(i);
みたいな感じで
書き換えられるけどhogeから抜けたら消える初期値nulloptのoptional<A>をデフォルト値で渡せるのか知りたい
2021/10/06(水) 01:23:25.11ID:V3EBITWg
なにいってんだおめ
2021/10/06(水) 01:31:37.67ID:V3EBITWg
nullopt以外が渡されたらそのA&に対して、
nulloptが渡されたらスタックにAを構築したうえでそのA&に対して操作したい、ってこと?

それはvoid hoge(int& p1, A& p2 = デフォルト値)でいけるんじゃないかい
2021/10/06(水) 01:49:32.28ID:E9G/hK4q
伝わらないようなので、コード書きました
https://wandbox.org/permlink/HyOX0jEBR4glCT01
2021/10/06(水) 03:08:52.59ID:3d8zh1Pt
>>493
やりたいことは std::optional<A>& ではなくて std::optional<A&> 的なことだろ。
しかし std::optional は参照を保持できないのでそういうときのために std::reference_wrapper がある。
コードにしたらこんな感じ。
https://wandbox.org/permlink/qEaoGDWFh7LmzE4m
2021/10/06(水) 06:31:33.91ID:lNsYT/rw
部分特殊化できないのは関数テンプレートだよな

template<class T1, class T2>
struct test {
void fig1();
void fig2();
void fig3();
};

template< > void test<void, void>::fig1(); //ok
template<class T1> void test<T1 , void>::fig2(); //error
template<class T2> void test<void, T2 >::fig3(); //error

クラステンプレートなのに弾かれるのは何で?
2021/10/06(水) 06:43:32.28ID:Cv4NDZSF
その部分特殊化されたtest(構造体)が定義されてないからだね
先にtestの部分特殊化を書けば通る
2021/10/06(水) 07:59:10.51ID:E9G/hK4q
>>494
std::reference_wrapperは知りませんでした
std::optional<A>をstd::optional<A*>にしてconstのままいじれるようにした気分なので
実質無理ってことなのかなぁと思いますが…
ありがとうございます
2021/10/06(水) 08:17:01.00ID:fON1wZ9Y
>>475
普通はオーバーロードだな。デフォルトを指定させたいのならnullobjectを始めとする定数オブジェクトかね。

nullポインタとか空のスマートポインタとかはエラーの元だから避けたいところ。
2021/10/06(水) 08:26:08.77ID:E9G/hK4q
>>497
自己レスです
いずれにしても呼び出し元を変更せずに要件を満たせそうな唯一の方法っぽいので解決ですね
(私は>>475ではありません)
2021/10/06(水) 08:34:45.86ID:4yqQ2QZ4
今は継承はなるべく使わない、がデフォなのかな
2021/10/06(水) 09:11:04.83ID:lTl3I+RT
クラステンプレートがナウい
2021/10/06(水) 09:13:14.40ID:lTl3I+RT
とはいえ、いきなりテンプレートにするのはハードル高いので、
結局は、継承クラスをいくつか作ってみてテンプレート化を試すことになる
2021/10/06(水) 09:41:21.39ID:DE23Rkof
>>498
> 普通はオーバーロードだな。
これに一票
2021/10/06(水) 10:03:37.43ID:7OUEgWer
>>489
gcc7でも-O2つけるとダメだね
つけなきゃ一致するけど
2021/10/06(水) 10:45:35.19ID:Cv4NDZSF
デフォとかナウいとかアホかと
2021/10/06(水) 12:20:32.60ID:iqYhGyd9
最適化オプションの違いで挙動が変わるようなコードはそもそもダメだって理解してくれよ
2021/10/06(水) 13:11:05.10ID:BBSbIN5v
インテルコンパイラはもう規格満たしてないだろってくらい滅茶苦茶に挙動を変える
gccなら、最適化で結果が変わるようなコードはダメコードと言って良いと思う
2021/10/08(金) 05:56:22.58ID:Xasiu/5n
>>496
遅レスすまそ
testなら部分特殊化できるのはわかるんだが
その場合クラス定義の全部を書き直すよな

template<class T1>
struct test<T1, void>
{
void fig1();
void fig2(); //特殊化したいのはここだけ
void fig3();
};

fig1とfig3を一次テンプレートと同じ内容で
書き直さにゃならんかね
2021/10/08(金) 23:05:08.47ID:xNy0cJty
関数テンプレート内でラムダ式使おうとしたらコンパイルできない

template<class T> void hoge(){
 auto func = [](){return 0;};
}

int main(){
 hoge<int>();
 return 0;
}


in instantiation of function template specialization 'hoge<int>' requested here
と出るが、何がだめなのかよくわからん
2021/10/08(金) 23:18:07.74ID:ZAq25yo3
>>509
そのメッセージは「関数テンプレートはここで特殊化 (テンプレート引数を当てはめて具体的な型に展開) されたやで」
というメッセージで、普通は他の警告やエラーの補足として出てくる。 なんか警告が一緒に出てない?

func が定義されとるけど使ってないという警告は出てくるけど無視して問題ない警告なのでコンパイルできないってことはない。
警告をエラー扱いにするオプションを付けてたりしない?
2021/10/08(金) 23:23:01.42ID:awgtN1Ul
C+pod
https://toyota.jp/cpod/images/sec1-sld-img2.jpg
2021/10/08(金) 23:28:30.45ID:ZAq25yo3
>>511
C++20 では std::is_pod や POD の概念自体が非推奨になってるぞ。
次あたりでは廃止されるんとちゃうか。
2021/10/09(土) 21:11:49.30ID:PhB5rfBq
あるラムダ式が他のラムダ式をコピーするとき、参照キャプチャにするかコピーキャプチャにするか迷うんですが、皆さんはどういう基準で決められてますか
2021/10/09(土) 21:14:22.61ID:yAn344zh
https://ideone.com/wq0CY8
やたーセマフォできたよ。

これバグってるかな?
2021/10/09(土) 21:17:39.52ID:yAn344zh
>>513
コピーキャプチャはコピーなので、それ相応のリソースを食う。
基本は参照キャプチャにしている。
2021/10/10(日) 01:44:21.88ID:qGt3mQky
破壊的代入の余地が無いようする
つまりコピーを第一の選択肢として考えるする
2021/10/10(日) 01:50:32.12ID:qGt3mQky
*thisはさすがに参照にすることが多いが(だいたいコピコンがあるとも限らないし、
とはいえ参照コピーしてパラメータに対する破壊的代入を許すと思想的に重箱読みになって気持ち悪い気がするし、
参照渡ししたオブジェクトは一般にスレッドローカルとは言い切れなくなることから
スレッドセーフと断言しにくくなるというのは実害に数えて良いと思う
入れ子になったラムダ式の奥深くでそれをやられると、いつ排他制御すべきなのかが全くワケワカメになりかねない
2021/10/10(日) 04:41:44.62ID:/ScOmKIj
>>516
だとすると一番効果的なのは
C++でコード書くこと自体をやめることだな
あんたの場合は
2021/10/10(日) 07:01:43.04ID:H3uBjuzu
>>516
コピーキャプチャが第一選択肢という結論は分かるが
それ以外の説明が完全に意味不明
2021/10/10(日) 09:28:13.64ID:lWUpu20f
意図しない破壊を防ぐにはキャプチャしなきゃいいだけ
それを参照のせいにするゴミはプログラマの資質がない
2021/10/10(日) 09:31:55.66ID:MbdCJRMe
とりあえずで[&]で書いてるな
丁寧にやりたければ変数ごとに考えて明示する
2021/10/10(日) 09:34:15.67ID:lWUpu20f
コピーのコストに無頓着なやつは11以後のC++に向かないな
2021/10/10(日) 10:09:31.41ID:B/tc3JZb
スレッド立ち上げるとかファイル書くとかクソ重い操作が伴う時にコピーコスト気にしてもしょうがない
場合によるとしか
2021/10/10(日) 10:37:13.21ID:2ZvzU42q
どこでも使う汎用性高いものなら問題が起きる前に[=]にしてる
逆に[&]はよほど安全だと思わない限り使わない
2021/10/10(日) 10:45:00.67ID:qGt3mQky
>>522
スレッドセーフをどう保証するかに無頓着な香具師はマルチスレッドプログラミングに向かんわ

>>518>>519
低レベルなレスどうも
ラムダ式の成り立ちを知らなかったり
どのように使われるか想像できなかったり
使ったこと無いんじゃね;;;
2021/10/10(日) 10:59:19.31ID:lWUpu20f
>>525
スレッドがどうたらはおまえさんが勝手に言い出したことで元質問にはない
まさかとは思うがコピーしてりゃスレッドセーフなんて主張はしてないよな
2021/10/10(日) 11:13:11.28ID:qGt3mQky
ラムダ式は一般にラムダ式を定義したスコープの外に持ち出され、予見できないタイミングで使われうる
参照キャプチャだと
(1) ラムダ式が使われるタイミングで参照xの参照先が存在することが保証されていなければならない
(2) ラムダ式が使われるタイミングで参照xの参照先へのアクセスが他のスレッドと競合しないことが保証されていなければならない
とゆー2条件をクリアする必要がある。
コピーキャプチャだと(オブジェクトがディープコピーなら)どっちの配慮も不要
参照キャプチャして(1)、(2)を満たして安心できるのは、イミュータブルなオブジェクトだけ……!
2021/10/10(日) 11:14:48.07ID:qGt3mQky
>>526
ラムダ式、が含意する事柄について不十分な理解なレスktkr、
危険プログラマー認定のレベル3ぐらいやな;;;
2021/10/10(日) 11:18:00.19ID:B/tc3JZb
>>527
ラムダ式をスコープ外に持ち出すなんてレアケースを「一般に」とか言われましても
2021/10/10(日) 11:28:18.85ID:2ZvzU42q
遅延評価されるものはよくコンテナに入れて後でぶん回されるから・・・
2021/10/10(日) 11:28:30.83ID:qGt3mQky
>>529
定義するのと使う(評価する)のを同じスコープ内でやるならラムダ式使うまでもないじゃん?
ていうか使うまでもないんですよ
>>529はアレな人?
2021/10/10(日) 11:38:17.37ID:QniiN4Lz
スコープ内の変数をキャプチャする処理をスレッドで動かす場合は普通にラムダ式を使うと思うが。
2021/10/10(日) 11:39:34.18ID:B/tc3JZb
>>531
はぁ?お前これしないの?ラムダ式のユースケースって9割方この類だろ
std::functionに突っ込んではるか遠くにぶん投げたりコンテナに詰め込んだりするのだけがラムダ式の使い道だと思ってるの?
std::sort(v.begin(), v.end(), [](int a, int b){/*...*/});
2021/10/10(日) 11:57:37.17ID:tv4afNG+
みなさんスレッドセーフにしたいときはスレッドセーフになる様に書きましょう
2021/10/10(日) 12:13:39.02ID:KKHdhYPj
>>522
11以前でも
2021/10/10(日) 12:21:43.80ID:Ld3aFVRt
任意のスレッド安全性を実現するのはゼロコストでは不可能だから
必ずシングルスレッドで実行される保障がある場合などはあえてスレッド安全性を捨てることもある
2021/10/10(日) 12:31:34.49ID:6/7jGiIK
std::conj() に double を渡したら std::complex<double> にキャストされるのが嫌なので、double を渡したら何もしないで double を返し、std::complex<double> を渡したら std::conj() と同じ動作をするオーバーロード関数 conj() を作ろうかと思うのですがアリですか?

なぜ std::conj() がそういう動作じゃないのか不思議で、何か見落としてたら教えてください
2021/10/10(日) 12:36:51.51ID:2ZvzU42q
こここ・・こういうこと?

(A)キャプチャが必要でスコープ内で実行までされるケース
(B)キャプチャが必要でスコープ外まで実行が遅延されるケース
(B-1)ラムダ式生成時と実行スレッドが同じケース
(B-2)ラムダ式生成時と実行スレッドが違うケース

(A)なら全員「[&]で問題があるケースはない」と考えている
(B-1)は好みが別れているところ
(B-2)は好みが別れているところで、さらにキャプチャされる変数側をスレッドセーフにするかどうも好み

[&]と[=]がよく分からない人はコチラ
https://ideone.com/OQS113

以下個人的意見
スレッドセーフにするコストは結構高い(開発・実行・保守全てで)ので、競合させずに遅延可能ならそれに越したことはないと考えている
ようはコピーするコストをそれほど高くは見積もっていない
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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