[過去ログ] C++相談室 part156 (1002レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
1(1): 2021/05/19(水)10:55 ID:LZZifCH2(1/2) AAS
前スレ
C++相談室 part155
2chスレ:tech
2: 2021/05/19(水)11:23 ID:b5zC4CMw(1) AAS
乙
3: 2021/05/19(水)11:31 ID:FIiQfBQ7(1/2) AAS
乙でございます
4: 2021/05/19(水)11:33 ID:psqzmlBB(1) AAS
乙python
5(1): 2021/05/19(水)11:36 ID:FIiQfBQ7(2/2) AAS
前スレの>>989
> 可変個の参照の組 (vectorでいい) を関数 hoge に渡したいときって、hoge が vector< reference_wrapper<T> > を取るようにして
> hoge({ref(A), ref(B), ref(C)})
> みたいに呼ぶか、可変引数テンプレートを使って hoge の中でパースするかっていうのが普通のやり方かな?
なんですが、もしかして reference_wrapper って構築時に左辺値を渡したらそれの参照を保持してくれる?
だとしたら
hoge({A, B, C})
と呼べるしかなりスッキリしますね
hoge 内でいちいち get() しないといけないのはダルいですが……
6(1): 2021/05/19(水)12:17 ID:5AVKLAl8(1/6) AAS
継承や委譲との付き合い方がよく分からなくなった
あるクラスの機能を全部持っていてほしいが is-a 関係がないとかで継承関係にはないように思える場合ってどうすんの
例えば一辺の長さを表す変数やはみ出し判定メソッドを持つ「グリッド座標クラス」があったとして、今「オセロを解くクラス」を作りたいとき
オセロを解くこと is a グリッド座標では全くないし継承するのは頓珍漢に思える
一方で「オセロを解くクラス」がグリッド座標のインスタンスを委譲として持っていたとして、盤の大きさとかはみ出し判定メソッドにわざわざ「グリッド座標クラス」のインスタンスを通してアクセスするのも果たして正しいだろうか
例えば盤面 a と盤面 b を同時に持ったりもするだろうが、a.size() とか b.size() は同じものを表すのでこのようにアクセスするのは可読性を損なう
だから「オセロを解くクラス」は盤面の大きさとかはみ出し判定メソッドを自分のメンバとして持っていてほしいが、継承するべきようにも思えない
7(1): 2021/05/19(水)12:37 ID:mqAmVEur(1/5) AAS
複数の盤面持つんならメンバで持つ一択だと思うけど
「解くクラス」に外部からはみ出し判定アクセスするのもおかしな話だけど
描画の都合とかで外部からアクセスするのが欠かせないなら、インデックス受け取って盤面の参照返すメンバ関数でも用意すればいい
8(1): 2021/05/19(水)12:44 ID:mqAmVEur(2/5) AAS
あ、あるいは解くクラスが単に外部の盤面を参照する形でもいいかもね
9: 2021/05/19(水)12:46 ID:5AVKLAl8(2/6) AAS
>>7
> 複数の盤面持つんならメンバで持つ一択だと思うけど
「オセロを解く」といった時点で盤の大きさ等決まるんだから、自分のメンバとして基本的な機能持っててほしいと思うんですが、偏った考え方ですかね
> 「解くクラス」に外部からはみ出し判定アクセスするのもおかしな話だけど
そう思います
10: 2021/05/19(水)12:47 ID:5AVKLAl8(3/6) AAS
>>8
それはインスタンスとして盤面を持つという意味ではなくですか?
11(1): 2021/05/19(水)12:51 ID:NOe9g/vN(1) AAS
フロント部分とオセロを解くソルバー部分で持ち方変えるってのが普通
12: 2021/05/19(水)12:52 ID:mqAmVEur(3/5) AAS
そう、内包しようとしない方が自然かもしれない
(読んだ範囲で勝手に考えてるだけだけど)
例えばその解くクラスってのがAI的に自動で解くクラスなら、じゃあその対戦相手に同じ(だがインスタンスは別)AIや
プレイヤーが参戦したらどうなるんだ?と考えると
盤面は独立してるほうが自然な気はする(個人の見解です
13(1): 2021/05/19(水)12:54 ID:A2sERbZl(1/2) AAS
>>6
オセロを解くアルゴリズムとオセロをプレイするモデル次第なのでなんとも。
まあ、オセロを解くんだったら多数のオセロ盤を持つだろうから、グリッドクラスを派生させてオセロ盤クラスを作るだろうな。
人間がオセロをプレイするのを素直にモデル化してもいいけど、ゲーム機のオセロゲームをプレイするようにモデル化したほうが、オセロを解く側のミスや負担が減る。
14: 2021/05/19(水)13:23 ID:5AVKLAl8(4/6) AAS
>>11
フロント部分って今の場合だと「オセロクラス」ってことですか?
つまり「オセロクラス」と「オセロを解くクラス」が、どちらがどちらを含むではなく、やり取りしあって動くべきだということですか?
15(1): 2021/05/19(水)13:26 ID:5AVKLAl8(5/6) AAS
>>13
派生って継承ってことですか?
つまり必ずしも is-a を満たさなくても機能を全部引き継ぐなら継承は是 (あるいはそうモデル化するのが良い) ということでしょうか
16: 2021/05/19(水)14:13 ID:TD1RuTos(1/2) AAS
かんたんだろ
色々判定してくれるオセロ妖精すなわち神を作ればいい
17: 2021/05/19(水)14:28 ID:mqAmVEur(4/5) AAS
>is-a を満たさなくても機能を全部引き継ぐなら
どちらも自分で書いてるしグリッドクラスも継承を想定して作れるんだからそれでいいとおも
他人の書いた継承を想定してなさそうなのはやめといた方がいいけどね
てかis-a,has-aはあくまで迷ったときの指針に過ぎんし自分で継承が良さそうと感じたならそれで正解だよ
18(1): 2021/05/19(水)14:43 ID:A2sERbZl(2/2) AAS
>>15
この場合、is-aは「グリッドとして同一視できる」を意味するから、オセロ盤をグリッドとして扱うことができるのなら継承もあり。
ただc++の継承は、継承元を総称として扱うという強い意味(継承元と派生クラス全体の強い結びつき)もあるのに注意。
オセロ盤とかその他のゲーム盤とかのクラスを(グリッドとして)使うということでもなければ、継承しないほうが設計の自由度を保てる。
19: 2021/05/19(水)14:53 ID:5AVKLAl8(6/6) AAS
>>18
> ただc++の継承は、継承元を総称として扱うという強い意味(継承元と派生クラス全体の強い結びつき)もあるのに注意。
まさに、そういった意味論的なところで悩んでいます
まあ実際にオセロソルバを作ろうとしているわけではないのですが、同じような局面に何度も出くわして、継承も委譲もどうも適切でないように思えて最終的に「グリッドクラス」の中身をコピペして「オセロソルバクラス」を作るようなこともしばしばしてしまいます
20: 2021/05/19(水)15:26 ID:mqAmVEur(5/5) AAS
そんなん言い出したらメタプログラミングで取り入れるメンバを選択するための継承なんか全部アウトだぞ
STL内部でやってるようなのも全部
ていうか
>まあ実際にオセロソルバを作ろうとしているわけではないのですが
>まあ実際にオセロソルバを作ろうとしているわけではないのですが
>まあ実際にオセロソルバを作ろうとしているわけではないのですが
21: 2021/05/19(水)15:43 ID:LZZifCH2(2/2) AAS
継承でできることを別の手段でもできるって言ってるだけでは説得力がない
そんなん言い出したらC++でできることをCで擬似コード書けるしな
特にコード量が増える「別の手段」を推奨するには
格段に強い理由がないと誰も動かせない
22(1): 2021/05/19(水)16:02 ID:XxOLfc+T(1/2) AAS
cpprefjp によると std::swap の実装って
void swap(T& a, T& b){
auto tmp = move(a);
a = move(b);
b = move(tmp);
}
みたいな感じですよね?
よくされる「move された後のオブジェクトはどうなってる保証もないのでもう触るべきでない」みたいな説明に照らせば、上のコードは move した後のオブジェクトを再利用してるけど大丈夫なのかなって思ってしまいます
大丈夫なんでしょうか?
また、参照をmoveしたら当然参照元のオブジェクトが「どうなってる保証もない」と考えるべきなんでしょうか?
23: 2021/05/19(水)16:39 ID:XxOLfc+T(2/2) AAS
もう一個質問させてください
引数に参照をとる関数に一時オブジェクトを渡したいこともあるんですが、この場合は const参照か右辺値をとる関数としてオーバーロードするしかないですよね?
24: 2021/05/19(水)16:43 ID:TD1RuTos(2/2) AAS
>MoveConstructibleかつMoveAssignable
こうなってるからヨシ!
25(1): 2021/05/19(水)19:24 ID:8oBHesVz(1) AAS
>>22
move後の変数は、読み取った場合の値はどうなってるか保証できないが、
値を書き込むことは正常に出来る事が保証されていると聞いた。
破棄することや、初期化することも問題ない。
26: ◆QZaw55cn4c 2021/05/19(水)19:54 ID:Y2/6iGxL(1) AAS
>>1
お疲れ様です
27(1): 2021/05/19(水)20:51 ID:aTtniYy+(1) AAS
>>25
moveコンストラクタは呼ばれないの?
呼ばれるのなら保証するのは自分自身なのでは?
28: 2021/05/20(木)02:43 ID:UJvm/t/I(1) AAS
>>27
moveコンストラクタは、変数定義を
TYPE x = y;
の形式で書いた場合に y が右辺値の場合に呼び出されるだけ。
move代入は、
x = y;
の形式で書いた場合に y が右辺値の場合に呼び出されるだけ。
後者の場合、xがmove後であるかどうかは関係ない。
変数xの中身をmove後のxへの書き込み、xの破棄、x.init()などとしての
再初期化が「保証される」というのは、保証されるようにSTLライブラリなどが
省1
29: 2021/05/21(金)05:29 ID:J+Oc/LGb(1) AAS
T が値なら終了して、vector<T> なら再帰的に自分を呼ぶ関数を作りたいのですが、T が vector (あるいはコンテナ) かどうかで分岐する処理ってどうやって書くのが良いですか
あと近い話題で、+ 演算子をオーバーロードして vector + vector が結合された vector を返すようにするのってナシですかね?(string のように)
要素同士の和をとるのと紛らわしいですか?
cat(vector, vector) とかの方が良いかな
30(3): 2021/05/21(金)06:16 ID:682YZm8K(1/2) AAS
固定長文字列クラスってないんですかね
template<int N> void hoge(string s){
……
assert(N == s.size());
array<int, N> a;
……
}
なる関数を呼び出すときにテンプレートパラメータを省略したいんです
s が固定長なら s から N を推論してくれますよね
31(1): 2021/05/21(金)06:29 ID:682YZm8K(2/2) AAS
あるいは hoge の引数を costexpr に限る方法なんかがあれば、N は必ずコンパイル時に推論できるようになるの思うので、もしそういうものがあればそれでも大丈夫です
32: 2021/05/21(金)11:15 ID:pMLUvwAV(1) AAS
もしかして、C++11に対応したSTLで、BSD/MIT 系ライセンスのものは存在してませんか?
・apache-stlは、2008年くらいで開発が終了しているようです。
・msvc用のstlはapacheライセンスですが、vcruntime.hが存在しないと
エラーになるようです。
33: 2021/05/21(金)12:27 ID:anlX8gXg(1) AAS
apacheで良ければllvm
34(1): 2021/05/21(金)15:55 ID:FMNTAZuF(1) AAS
>>30-31
これマジキボンヌなので何卒よろしくお願いします
35(2): 2021/05/21(金)16:07 ID:wQUXYA+s(1) AAS
>>30
よくわからんが何で長さの相違を型の相違にしたいんだ?
文字列リテラルならこういう手があるけど
template <int N> void hoge(const char(&s)[N])
{
}
36(1): 2021/05/21(金)16:09 ID:zwURlIka(1) AAS
>>34
整数のテンプレート引数を使って、std::stringを継承した文字列クラステンプレートを作ればなんとかなりそう。試してないけど。
std::stringの継承はけっこうクセがあった気がするから、自分で調べてね。
37(1): 2021/05/21(金)16:18 ID:cnTkitrU(1) AAS
>>30
>テンプレートパラメータを省略したいんです
の理由がただお遊びレベルのような気がしてスルーしてたけど
固定長の文字列クラスは標準には無い、欲しけりゃ探すか自分で作れ、それか>>35
38: はちみつ餃子 ◆8X2XSCHEME 2021/05/21(金)16:51 ID:JT5uzYpW(1) AAS
コンパイル時プログラミングのための機能を満載したライブラリ Sprout がある。
constexpr 対応した文字列クラスもある。
外部リンク:boleros.hateblo.jp
ボレロ村上が亡くなってもう一年以上たったんだなぁ……。
Sprout のメンテナンスを引き継ぐ大きな組織とかないのかね?
いっそ Boost に編入するとかでもよいような気がするが。
39(2): 2021/05/22(土)04:55 ID:Dt9VIAZx(1) AAS
>>35
> 何で長さの相違を型の相違にしたいんだ?
すみません。どういう意味でしょうか
やりたいことは、関数に渡した定文字列の長さをコンパイル時定数として扱うことです
> 文字列リテラルならこういう手があるけど
ありがとうございます
これが現在やりたいことに最も近いです
2つの文字列リテラルの共通部分列の長さをコンパイル時定数として扱うみたいなこともできそうで、ワクワクしています
>>36-37
ありがとうございます
省3
40(1): 2021/05/22(土)10:24 ID:zUe7A7la(1) AAS
固定長文字列ってCOBOL以外にあるの?
FORTRANにも無いしCにも無い
現行言語には存在すらしない
昔から特殊技術で需要が少ない
41: 2021/05/22(土)10:31 ID:tdkMyXe1(1) AAS
malloc使わなかったらcも固定長でしょ
あとsql
42: 2021/05/22(土)12:24 ID:oerUOwsX(1) AAS
>>39
文字列長ごとにメソッドが別になってプログラムサイズの肥大化に繋がる。
スタックに文字列を全部乗っけて(若干の)スピードアップを狙うこともあるけど、そのときでも「〇〇文字以下」みたいにサイズ制限するくらい。Delphiの文字列がそうだったと思う。
43: 2021/05/22(土)14:32 ID:uYvLH1Gz(1) AAS
>>40
FORTRANにもあるしPascalにもあるぞ
需要じゃなくてお前の知識が少ないだけだろw
44(1): 2021/05/22(土)16:10 ID:F6wYMINE(1) AAS
clangで、#includeや#include_nextした全てのインクルードファイルの
パスの一覧をテキストファイルに出力することは出来ますか?
45(1): はちみつ餃子 ◆8X2XSCHEME 2021/05/22(土)18:00 ID:+NInCFK+(1) AAS
>>44
-MD オプションかな。 これは gcc と clang で共通。
46: 2021/05/23(日)06:05 ID:NALp7ema(1/3) AAS
すみません
>>5の方法で可変個の参照の組を関数に渡そうとして行き詰まりました
hoge の定義を
template<class T> void hoge(vector< reference_wrapper<T> >);
として、hoge({a, b, c}) と呼んだら T が推論できないとエラーが出ました
47(1): 2021/05/23(日)07:05 ID:apxwsDfF(1/10) AAS
a, b, c がfoo_t型だとして
単に型foo_tを明示して hoge<foo_t>({ a, b, c}) と呼んだら良いんジャネーノ;;;
48(1): 2021/05/23(日)07:07 ID:apxwsDfF(2/10) AAS
質問ですがvirtualでないクラスFoo(つまりdynamic_cast適用不能)のオブジェクトをthrowしたら
catchできます?
49: 2021/05/23(日)07:30 ID:NALp7ema(2/3) AAS
>>47
ありがとうございます
ただ、なぜに推論できないのでしょうか
template<class T> void hoge(vector< reference_wrapper<T> >);
と
template<class T> void hoge(vector<T>);
が両方あってどっちか判断できないって話なら分かるんですが
50(1): 2021/05/23(日)07:33 ID:8ydzk+Rl(1) AAS
reference_wrapper<T> をテンプレート型として認識できないからでしょ
51: 2021/05/23(日)07:51 ID:NALp7ema(3/3) AAS
>>50
ありがとうございます
コンテナの入れ子の中に T があっても推論してくれる例を知っていたので、いつでもできるのだと誤解していました
52: 2021/05/23(日)08:00 ID:apxwsDfF(3/10) AAS
{ 1, 2, 3 }というだけではstd::vector<int>なのかstd::vector<double>なのか(ひょっとしたらstd::vector<long>とかかも??)
わからないからという理由
自動型変換結果とのマッチングは追求しだすときりが無いので規格でどの範囲でやるか制限がかかっているたはず
53(1): 2021/05/23(日)08:08 ID:p04S1woO(1/2) AAS
>>48
C++はintだって投げられるし捕まえられるぞ
上下前次1-新書関写板覧索設栞歴
あと 949 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.206s*