X



C++相談室 part156
■ このスレッドは過去ログ倉庫に格納されています
0002デフォルトの名無しさん
垢版 |
2021/05/19(水) 11:23:50.45ID:b5zC4CMw
0004デフォルトの名無しさん
垢版 |
2021/05/19(水) 11:33:27.40ID:psqzmlBB
乙python
0005デフォルトの名無しさん
垢版 |
2021/05/19(水) 11:36:23.16ID:FIiQfBQ7
前スレの>>989
> 可変個の参照の組 (vectorでいい) を関数 hoge に渡したいときって、hoge が vector< reference_wrapper<T> > を取るようにして
> hoge({ref(A), ref(B), ref(C)})
> みたいに呼ぶか、可変引数テンプレートを使って hoge の中でパースするかっていうのが普通のやり方かな?

なんですが、もしかして reference_wrapper って構築時に左辺値を渡したらそれの参照を保持してくれる?
だとしたら
hoge({A, B, C})
と呼べるしかなりスッキリしますね
hoge 内でいちいち get() しないといけないのはダルいですが……
0006デフォルトの名無しさん
垢版 |
2021/05/19(水) 12:17:48.45ID:5AVKLAl8
継承や委譲との付き合い方がよく分からなくなった

あるクラスの機能を全部持っていてほしいが is-a 関係がないとかで継承関係にはないように思える場合ってどうすんの
例えば一辺の長さを表す変数やはみ出し判定メソッドを持つ「グリッド座標クラス」があったとして、今「オセロを解くクラス」を作りたいとき

オセロを解くこと is a グリッド座標では全くないし継承するのは頓珍漢に思える
一方で「オセロを解くクラス」がグリッド座標のインスタンスを委譲として持っていたとして、盤の大きさとかはみ出し判定メソッドにわざわざ「グリッド座標クラス」のインスタンスを通してアクセスするのも果たして正しいだろうか
例えば盤面 a と盤面 b を同時に持ったりもするだろうが、a.size() とか b.size() は同じものを表すのでこのようにアクセスするのは可読性を損なう
だから「オセロを解くクラス」は盤面の大きさとかはみ出し判定メソッドを自分のメンバとして持っていてほしいが、継承するべきようにも思えない
0007デフォルトの名無しさん
垢版 |
2021/05/19(水) 12:37:51.61ID:mqAmVEur
複数の盤面持つんならメンバで持つ一択だと思うけど
「解くクラス」に外部からはみ出し判定アクセスするのもおかしな話だけど
描画の都合とかで外部からアクセスするのが欠かせないなら、インデックス受け取って盤面の参照返すメンバ関数でも用意すればいい
0009デフォルトの名無しさん
垢版 |
2021/05/19(水) 12:46:25.42ID:5AVKLAl8
>>7
> 複数の盤面持つんならメンバで持つ一択だと思うけど
「オセロを解く」といった時点で盤の大きさ等決まるんだから、自分のメンバとして基本的な機能持っててほしいと思うんですが、偏った考え方ですかね


> 「解くクラス」に外部からはみ出し判定アクセスするのもおかしな話だけど
そう思います
0012デフォルトの名無しさん
垢版 |
2021/05/19(水) 12:52:13.78ID:mqAmVEur
そう、内包しようとしない方が自然かもしれない
(読んだ範囲で勝手に考えてるだけだけど)
例えばその解くクラスってのがAI的に自動で解くクラスなら、じゃあその対戦相手に同じ(だがインスタンスは別)AIや
プレイヤーが参戦したらどうなるんだ?と考えると
盤面は独立してるほうが自然な気はする(個人の見解です
0013デフォルトの名無しさん
垢版 |
2021/05/19(水) 12:54:28.27ID:A2sERbZl
>>6
オセロを解くアルゴリズムとオセロをプレイするモデル次第なのでなんとも。

まあ、オセロを解くんだったら多数のオセロ盤を持つだろうから、グリッドクラスを派生させてオセロ盤クラスを作るだろうな。
人間がオセロをプレイするのを素直にモデル化してもいいけど、ゲーム機のオセロゲームをプレイするようにモデル化したほうが、オセロを解く側のミスや負担が減る。
0014デフォルトの名無しさん
垢版 |
2021/05/19(水) 13:23:50.34ID:5AVKLAl8
>>11
フロント部分って今の場合だと「オセロクラス」ってことですか?
つまり「オセロクラス」と「オセロを解くクラス」が、どちらがどちらを含むではなく、やり取りしあって動くべきだということですか?
0015デフォルトの名無しさん
垢版 |
2021/05/19(水) 13:26:27.55ID:5AVKLAl8
>>13
派生って継承ってことですか?
つまり必ずしも is-a を満たさなくても機能を全部引き継ぐなら継承は是 (あるいはそうモデル化するのが良い) ということでしょうか
0016デフォルトの名無しさん
垢版 |
2021/05/19(水) 14:13:31.63ID:TD1RuTos
かんたんだろ
色々判定してくれるオセロ妖精すなわち神を作ればいい
0017デフォルトの名無しさん
垢版 |
2021/05/19(水) 14:28:08.35ID:mqAmVEur
>is-a を満たさなくても機能を全部引き継ぐなら
どちらも自分で書いてるしグリッドクラスも継承を想定して作れるんだからそれでいいとおも
他人の書いた継承を想定してなさそうなのはやめといた方がいいけどね

てかis-a,has-aはあくまで迷ったときの指針に過ぎんし自分で継承が良さそうと感じたならそれで正解だよ
0018デフォルトの名無しさん
垢版 |
2021/05/19(水) 14:43:02.57ID:A2sERbZl
>>15
この場合、is-aは「グリッドとして同一視できる」を意味するから、オセロ盤をグリッドとして扱うことができるのなら継承もあり。

ただc++の継承は、継承元を総称として扱うという強い意味(継承元と派生クラス全体の強い結びつき)もあるのに注意。
オセロ盤とかその他のゲーム盤とかのクラスを(グリッドとして)使うということでもなければ、継承しないほうが設計の自由度を保てる。
0019デフォルトの名無しさん
垢版 |
2021/05/19(水) 14:53:47.60ID:5AVKLAl8
>>18
> ただc++の継承は、継承元を総称として扱うという強い意味(継承元と派生クラス全体の強い結びつき)もあるのに注意。

まさに、そういった意味論的なところで悩んでいます
まあ実際にオセロソルバを作ろうとしているわけではないのですが、同じような局面に何度も出くわして、継承も委譲もどうも適切でないように思えて最終的に「グリッドクラス」の中身をコピペして「オセロソルバクラス」を作るようなこともしばしばしてしまいます
0020デフォルトの名無しさん
垢版 |
2021/05/19(水) 15:26:58.77ID:mqAmVEur
そんなん言い出したらメタプログラミングで取り入れるメンバを選択するための継承なんか全部アウトだぞ
STL内部でやってるようなのも全部

ていうか
>まあ実際にオセロソルバを作ろうとしているわけではないのですが
>まあ実際にオセロソルバを作ろうとしているわけではないのですが
>まあ実際にオセロソルバを作ろうとしているわけではないのですが
0021デフォルトの名無しさん
垢版 |
2021/05/19(水) 15:43:24.71ID:LZZifCH2
継承でできることを別の手段でもできるって言ってるだけでは説得力がない
そんなん言い出したらC++でできることをCで擬似コード書けるしな

特にコード量が増える「別の手段」を推奨するには
格段に強い理由がないと誰も動かせない
0022デフォルトの名無しさん
垢版 |
2021/05/19(水) 16:02:58.49ID:XxOLfc+T
cpprefjp によると std::swap の実装って
void swap(T& a, T& b){
 auto tmp = move(a);
 a = move(b);
 b = move(tmp);
}
みたいな感じですよね?
よくされる「move された後のオブジェクトはどうなってる保証もないのでもう触るべきでない」みたいな説明に照らせば、上のコードは move した後のオブジェクトを再利用してるけど大丈夫なのかなって思ってしまいます
大丈夫なんでしょうか?
また、参照をmoveしたら当然参照元のオブジェクトが「どうなってる保証もない」と考えるべきなんでしょうか?
0023デフォルトの名無しさん
垢版 |
2021/05/19(水) 16:39:28.28ID:XxOLfc+T
もう一個質問させてください
引数に参照をとる関数に一時オブジェクトを渡したいこともあるんですが、この場合は const参照か右辺値をとる関数としてオーバーロードするしかないですよね?
0024デフォルトの名無しさん
垢版 |
2021/05/19(水) 16:43:38.10ID:TD1RuTos
>MoveConstructibleかつMoveAssignable
こうなってるからヨシ!
0025デフォルトの名無しさん
垢版 |
2021/05/19(水) 19:24:14.37ID:8oBHesVz
>>22
move後の変数は、読み取った場合の値はどうなってるか保証できないが、
値を書き込むことは正常に出来る事が保証されていると聞いた。
破棄することや、初期化することも問題ない。
0028デフォルトの名無しさん
垢版 |
2021/05/20(木) 02:43:42.49ID:UJvm/t/I
>>27
moveコンストラクタは、変数定義を
TYPE x = y;
の形式で書いた場合に y が右辺値の場合に呼び出されるだけ。
move代入は、
x = y;
の形式で書いた場合に y が右辺値の場合に呼び出されるだけ。
後者の場合、xがmove後であるかどうかは関係ない。

変数xの中身をmove後のxへの書き込み、xの破棄、x.init()などとしての
再初期化が「保証される」というのは、保証されるようにSTLライブラリなどが
作られているという意味で、コンパイラが保証するというわけではない。
0029デフォルトの名無しさん
垢版 |
2021/05/21(金) 05:29:55.67ID:J+Oc/LGb
T が値なら終了して、vector<T> なら再帰的に自分を呼ぶ関数を作りたいのですが、T が vector (あるいはコンテナ) かどうかで分岐する処理ってどうやって書くのが良いですか


あと近い話題で、+ 演算子をオーバーロードして vector + vector が結合された vector を返すようにするのってナシですかね?(string のように)
要素同士の和をとるのと紛らわしいですか?
cat(vector, vector) とかの方が良いかな
0030デフォルトの名無しさん
垢版 |
2021/05/21(金) 06:16:08.57ID:682YZm8K
固定長文字列クラスってないんですかね

template<int N> void hoge(string s){
 ……
 assert(N == s.size());
 array<int, N> a;
 ……
}
なる関数を呼び出すときにテンプレートパラメータを省略したいんです
s が固定長なら s から N を推論してくれますよね
0031デフォルトの名無しさん
垢版 |
2021/05/21(金) 06:29:04.74ID:682YZm8K
あるいは hoge の引数を costexpr に限る方法なんかがあれば、N は必ずコンパイル時に推論できるようになるの思うので、もしそういうものがあればそれでも大丈夫です
0032デフォルトの名無しさん
垢版 |
2021/05/21(金) 11:15:57.88ID:pMLUvwAV
もしかして、C++11に対応したSTLで、BSD/MIT 系ライセンスのものは存在してませんか?
・apache-stlは、2008年くらいで開発が終了しているようです。
・msvc用のstlはapacheライセンスですが、vcruntime.hが存在しないと
 エラーになるようです。
0035デフォルトの名無しさん
垢版 |
2021/05/21(金) 16:07:34.25ID:wQUXYA+s
>>30
よくわからんが何で長さの相違を型の相違にしたいんだ?

文字列リテラルならこういう手があるけど
template <int N> void hoge(const char(&s)[N])
{
}
0036デフォルトの名無しさん
垢版 |
2021/05/21(金) 16:09:26.25ID:zwURlIka
>>34
整数のテンプレート引数を使って、std::stringを継承した文字列クラステンプレートを作ればなんとかなりそう。試してないけど。
std::stringの継承はけっこうクセがあった気がするから、自分で調べてね。
0037デフォルトの名無しさん
垢版 |
2021/05/21(金) 16:18:16.28ID:cnTkitrU
>>30
>テンプレートパラメータを省略したいんです
の理由がただお遊びレベルのような気がしてスルーしてたけど
固定長の文字列クラスは標準には無い、欲しけりゃ探すか自分で作れ、それか>>35
0038はちみつ餃子 ◆8X2XSCHEME
垢版 |
2021/05/21(金) 16:51:46.16ID:JT5uzYpW
コンパイル時プログラミングのための機能を満載したライブラリ Sprout がある。
constexpr 対応した文字列クラスもある。
http://boleros.hateblo.jp/entry/20110926/1318115291

ボレロ村上が亡くなってもう一年以上たったんだなぁ……。
Sprout のメンテナンスを引き継ぐ大きな組織とかないのかね?
いっそ Boost に編入するとかでもよいような気がするが。
0039デフォルトの名無しさん
垢版 |
2021/05/22(土) 04:55:57.93ID:Dt9VIAZx
>>35
> 何で長さの相違を型の相違にしたいんだ?
すみません。どういう意味でしょうか
やりたいことは、関数に渡した定文字列の長さをコンパイル時定数として扱うことです


> 文字列リテラルならこういう手があるけど
ありがとうございます
これが現在やりたいことに最も近いです
2つの文字列リテラルの共通部分列の長さをコンパイル時定数として扱うみたいなこともできそうで、ワクワクしています


>>36-37
ありがとうございます
自作は想像だにしない失敗に繋がりそうなのでやめておきます


固定長文字列とか引数を constexpr に限るとかすごい便利な機能に思えるんですが、今後標準に入ることはあるんでしょうか
それとも僕の不理解で便利に見えるだけなんでしょうか
0040デフォルトの名無しさん
垢版 |
2021/05/22(土) 10:24:05.95ID:zUe7A7la
固定長文字列ってCOBOL以外にあるの?
FORTRANにも無いしCにも無い
現行言語には存在すらしない
昔から特殊技術で需要が少ない
0042デフォルトの名無しさん
垢版 |
2021/05/22(土) 12:24:13.54ID:oerUOwsX
>>39
文字列長ごとにメソッドが別になってプログラムサイズの肥大化に繋がる。

スタックに文字列を全部乗っけて(若干の)スピードアップを狙うこともあるけど、そのときでも「〇〇文字以下」みたいにサイズ制限するくらい。Delphiの文字列がそうだったと思う。
0044デフォルトの名無しさん
垢版 |
2021/05/22(土) 16:10:33.68ID:F6wYMINE
clangで、#includeや#include_nextした全てのインクルードファイルの
パスの一覧をテキストファイルに出力することは出来ますか?
0046デフォルトの名無しさん
垢版 |
2021/05/23(日) 06:05:08.87ID:NALp7ema
すみません
>>5の方法で可変個の参照の組を関数に渡そうとして行き詰まりました

hoge の定義を
template<class T> void hoge(vector< reference_wrapper<T> >);
として、hoge({a, b, c}) と呼んだら T が推論できないとエラーが出ました
0047デフォルトの名無しさん
垢版 |
2021/05/23(日) 07:05:25.07ID:apxwsDfF
a, b, c がfoo_t型だとして
単に型foo_tを明示して hoge<foo_t>({ a, b, c}) と呼んだら良いんジャネーノ;;;
0048デフォルトの名無しさん
垢版 |
2021/05/23(日) 07:07:18.56ID:apxwsDfF
質問ですがvirtualでないクラスFoo(つまりdynamic_cast適用不能)のオブジェクトをthrowしたら
catchできます?
0049デフォルトの名無しさん
垢版 |
2021/05/23(日) 07:30:24.57ID:NALp7ema
>>47
ありがとうございます
ただ、なぜに推論できないのでしょうか

template<class T> void hoge(vector< reference_wrapper<T> >);

template<class T> void hoge(vector<T>);
が両方あってどっちか判断できないって話なら分かるんですが
0051デフォルトの名無しさん
垢版 |
2021/05/23(日) 07:51:37.19ID:NALp7ema
>>50
ありがとうございます
コンテナの入れ子の中に T があっても推論してくれる例を知っていたので、いつでもできるのだと誤解していました
0052デフォルトの名無しさん
垢版 |
2021/05/23(日) 08:00:14.50ID:apxwsDfF
{ 1, 2, 3 }というだけではstd::vector<int>なのかstd::vector<double>なのか(ひょっとしたらstd::vector<long>とかかも??)
わからないからという理由
自動型変換結果とのマッチングは追求しだすときりが無いので規格でどの範囲でやるか制限がかかっているたはず
0056デフォルトの名無しさん
垢版 |
2021/05/23(日) 08:30:19.77ID:GrP2Tvrl
Emacs で LSP 使わず開発してる人いる?
おもしろ設定とか参考になるサイトあったら教えてほしい

flycheck しか入れてない
0058デフォルトの名無しさん
垢版 |
2021/05/23(日) 09:31:01.96ID:apxwsDfF
>>57
ありえん
1つのthrowに対し、呼び出し元のcatchで呼び出すべき(オーバーロードされた)関数シンボルを一意に列挙できるなら
アンワインド時にオーバーロードのしくみで例外ハンドラの解決を行えるかもしれないが、これは論理的に成り立たない
なぜなら、例えばintを例外をスローする関数foo()がbar()とbaz()から呼ばれているとして、
bar()にcatch (int)が書かれているのにbaz()に描かれていないとした場合、
bar()経由の呼び出しにおいては(オーバーロードされた)関数シンボルのリストに func(int)が含まれるのに対し、
baz()経由の呼び出しにおいては(オーバーロードされた)関数シンボルのリストに func(int)が含まれない、
となって一意にならず、throwした瞬間にどっちなのか解決不能
やっぱcatch側が(何が来るかわからない状態で)待ち受けているとしか考えられない
0059デフォルトの名無しさん
垢版 |
2021/05/23(日) 09:40:45.57ID:apxwsDfF
ちょっち補足すると、
bar()でtry { foo(); } catch (int ex) { .... } したときに handler(int)を例外ハンドラのリストに動的に登録し、
baz()ではtry { foo(); } catch (int ex) { .... } が無いからhandler(int)を例外ハンドラのリストに動的に登録しないようにすれば、
foo()でthrowしたときに最新の例外ハンドラのリストを参照することによって解決はギリ可能だが、
スタックとは別に例外ハンドラのリストに動的に管理するみたいなことをしているのかとカナーリ疑問に、
(例外がfall throughする関数の中にはゼロコストの奴も含まれるので、スタック上で細工して例外ハンドラのリストを更新管理することは不可能
0061デフォルトの名無しさん
垢版 |
2021/05/23(日) 09:52:50.26ID:apxwsDfF
exception_ptrの主な用途は、バックグランドスレッドからメインスレッドに、例外オブジェクトを持ち運ぶ、というものである。標準ライブラリにおいては、promiseとfutureの実装で使用される。
と書いてあってスレッド間をまたぐ用(promiseしたことを実行中に起きた例外を、promise完了を待っているやつに伝える)とき限定に見える

単純にcalleeからcaller側に飛ばす通常の例外ではどうなのや??

intやdoubleやconst char*を型情報とともに収容可能なexception_ptrみたいな構造体が絡んでいるのだろうとは思いまするが
0063デフォルトの名無しさん
垢版 |
2021/05/23(日) 10:08:43.53ID:vhcqGTpc
>>61
スレッドは関係ないぞ
同一スレッドでも監視ブロックを抜けrた後でrethrow_exceptionできるし
0064デフォルトの名無しさん
垢版 |
2021/05/23(日) 10:30:51.86ID:apxwsDfF
>>63
言わんとすることはわかりまするが
(そもそもpromise/futureのしくみも論理的には単なる継続なので単一スレッドでの実装もあり得るという意味でスレッドは関係無い
しかしrethrow_exception(ex)はrethrow_exception(ex)であってthrow exとは別の文やん??
本当に単純にcalleeからcaller側に飛ばす通常の例外も同じしくみなのかどうか、、、
0065デフォルトの名無しさん
垢版 |
2021/05/23(日) 10:45:18.88ID:apxwsDfF
スマン>>58>>59は撤回
やっぱ関数のオーバーロードで呼び出すべきハンドラを解決している可能性がありえまつね
というのはスタックにはreturn addressが積まれているので、throw intするfoo()は、
throwする瞬間に自分がbar()経由で呼ばれたのかbaz()経由なのか判定可能
あとはreturn addressに対して呼び出すべきハンドラ(のシンボルのリスト)を与えるテーブルがあれば、
関数のオーバーロードで呼び出すべきハンドラを解決できる
極力実行コストを低くする手となるとこれかなあ……
長々とスマンカッタ、継続調査しまつ
0066デフォルトの名無しさん
垢版 |
2021/05/23(日) 12:13:22.18ID:MJ9lD3tL
>>56
>Emacs で LSP 使わず開発

その発想がナンセンス
0067デフォルトの名無しさん
垢版 |
2021/05/23(日) 13:43:41.87ID:p+CWzw6b
>>66
lsp-mode インストールしてファイル開いてみたら「これはなんのプロジェクトにも属してないファイルだ」とか言って何もしてくれなかったもん
テキストエディタだぞ
単一ファイルのソースも普通に編集できるべきだ
0068デフォルトの名無しさん
垢版 |
2021/05/23(日) 13:53:03.07ID:P4UGjjTl
インストールさせるという選択肢である以上は
emacs側はそれをやるかどうかの選択をユーザに委ねていることになる
なのでNoという選択もありうる、とemacs側は考えている

選択肢が無く強制なら選択をさせずインストール現象もまた起こらない
インストールさせるということはYesかNoかをユーザが選ぶことができる仕組みになっているからだ
YesでもNoでもなく選択出来ないならインストールさせない仕組みになっているハズだ
ここでインストールできるということはユーザのYes/Noの意思が尊重されることに他ならない

選ぶ・選ばない・強制、などにおいて、選ぶことが出来る事象については何を選択してもいいし、emacs側もそれを容認している
0070デフォルトの名無しさん
垢版 |
2021/05/23(日) 14:27:22.85ID:vhcqGTpc
>>64
よくわからんが、こういうこと?
void caller()
{
exception_ptr ex;

ex = callee();

try
{
rethrow_exception(ex);
}
catch(double err)
{
cout << "What the hell does that mean?\n";
}
}

exception_ptr callee()
{
try
{
throw 0.1;
}
catch(...)
{
return current_exception();
}
}
0071デフォルトの名無しさん
垢版 |
2021/05/26(水) 14:25:57.68ID:h0MuFhR9
クラスAがクラスBのインスタンスをメンバに持つとき (移譲っていうんだっけ?)、Bのコンストラクタってどーやって呼ぶんよ
0073はちみつ餃子 ◆8X2XSCHEME
垢版 |
2021/05/26(水) 16:01:46.87ID:BWKw9sIj
C++20 からは std::string は constexpr 対応になっとるな。
実装が追いついとるかどうか知らんけど。
0076デフォルトの名無しさん
垢版 |
2021/05/27(木) 10:11:42.93ID:KxmxhHMB
なぁ…何気に…普通に…何の気なしに…以下の様なコードを書く…
textView1->get_source_buffer()->place_cursor(
textView1->get_source_buffer()->get_iter_at_line(minusList.front() - 1));
なんだけどさ…このplace_cursorの引数はiteratorなんだが…この一時的に作った無名の変数の寿命って…
どうなってるの?…ちなみに…place_cursorは&で受ける…やばいのかな?
0077デフォルトの名無しさん
垢版 |
2021/05/27(木) 10:35:07.24ID:KxmxhHMB
place_cursorを実行している段階では…生きている…そうだ…次のステップに移行すると…消える…らしい
ほんまかいなと思いますが…一応…信じておきます…
0080デフォルトの名無しさん
垢版 |
2021/05/27(木) 14:31:37.41ID:U0nLnJgd
勝手に消えるのは確かだが
いつ消えるかは確定出来ないんじゃないの?
次の行の実行中かも知れないし
もう少し生きてるかも知れない
関数抜けたら消えるだろうけど
0081デフォルトの名無しさん
垢版 |
2021/05/27(木) 14:35:50.64ID:P6misAvy
その、意味があるとかないとかを、どうやって判断するかと聞いてるんじゃないかね
0082デフォルトの名無しさん
垢版 |
2021/05/27(木) 14:57:58.21ID:THQ6jHMK
記述時に事細かに寿命を制御・確定できるような時制プログラミングを作ればいい
C++の場合だと新しい原理を作ればいい
0083デフォルトの名無しさん
垢版 |
2021/05/27(木) 15:03:35.45ID:kQVwJQto
> 参照が一時オブジェクトに束縛されている

一時オブジェクトが参照に束縛されている、だろ
ここではconstでない左辺値参照は含まない
0084はちみつ餃子 ◆8X2XSCHEME
垢版 |
2021/05/27(木) 15:10:56.23ID:tXzwBfxM
>>83
> 一時オブジェクトが参照に束縛されている、だろ

いいえ。 束縛されるのは参照で束縛するのはオブジェクトです。
0087デフォルトの名無しさん
垢版 |
2021/05/27(木) 15:30:34.22ID:kQVwJQto
いや、おかしいだろ
rand(); //ここで消えてしまう一時オブジェクトを
auto&& a = rand(); //引き止める(束縛する主体が参照で
客体が一時オブジェクトだぞ
0089はちみつ餃子 ◆8X2XSCHEME
垢版 |
2021/05/27(木) 15:46:15.37ID:tXzwBfxM
>>85
このへんのセクション内部ではどちらの表現もある。
https://timsong-cpp.github.io/cppwp/n3337/over.ics.ref

"自由変数と束縛変数"
https://ja.wikipedia.org/wiki/%E8%87%AA%E7%94%B1%E5%A4%89%E6%95%B0%E3%81%A8%E6%9D%9F%E7%B8%9B%E5%A4%89%E6%95%B0

このへんの数学的用語では束縛されているのは変数で、 ML 系とか Scheme とかでも一貫してこの用法に従ってるんだけど、
めんどいから私は「××との間に束縛を持つ」みたいな言い回しでどちらが主語なのか曖昧にしたりしてる。

今回の場合は >>79 で示した通りオブジェクトの寿命に関する項目での表現では束縛されているのは参照だから
それにならっただけでどっちがどっちでもまあ重要じゃないよ。
0090デフォルトの名無しさん
垢版 |
2021/05/27(木) 16:09:02.89ID:kQVwJQto
>>89
1つめのリンクでは
結合する主体は参照を宣言するコンテキストだね
結合される客体がオブジェクトである点は変わってない

数学や他言語がどうたらには付き合ってやんね

ちゃんとC++の話のなかで例えるなら
実体定義と外部宣言はどちらが使われる側と使う側なのか
のような話だろ
0091デフォルトの名無しさん
垢版 |
2021/05/28(金) 04:05:49.41ID:cE/PGHSY
そことは直接関係ないけど、cppreferenceの英語版って、英語として文法的におかしい
ことが有る気がする。主語が無くていきなり三人称単数現在のsが付いた動詞で
始まっている文章も、見出しの直後ならダメではないが、見出しの直後以外の
if節の後にあったりして、しかもそれがif節の中に繋がっていなくて、本来なら
主語を省略できない場合とか。
Microsoftの英語版はすらすら読めるけどcppreferenceの英語版は読めない。
0092デフォルトの名無しさん
垢版 |
2021/05/28(金) 04:22:43.88ID:bFqxphgp
int 配列の参照って
int (&a)[N]
であって
(int&) a[N]
じゃないよね?
後者は「参照の配列」を意味するようで変なのは分かるんだが、前者は前者でどこに&ついてんねんって感じなんだが
0094デフォルトの名無しさん
垢版 |
2021/05/28(金) 04:57:54.48ID:0J3ydS6A
>>92
>int (&a)[N]
それは、数学記号の様に読み取ることが出来る。
()は優先順位を変えているだけ。
優先順位に従って書いてみると、
a --> & --> [N] --> int
となる。これにより、
「a は、参照で、それは、[N] を指し、その要素は int である」
と読めて、もう少し自然な言語に直すと
「a は、参照で、それは、N要素の配列を指し、その配列の要素は int である」
となり、さらにわかり易くすると、
「a は、要素が int の配列を指している参照である」
となる。このように数学の式変形の様な工程を経ているだけの、単なる計算の様な
ものに過ぎない。
0095デフォルトの名無しさん
垢版 |
2021/05/28(金) 05:01:18.55ID:0J3ydS6A
>>94
[補足]
a --> & --> [N] --> int
を英語で読んでみると、
「a is & to [N] to int」
となる。& を「reference」、[N]を「N要素のarray」に置き換えてみると、
「a is reference to "N要素の配列" to int」
となる。日本語に直せば、
「aは、int 型の N要素の配列への参照」
となる。
0098デフォルトの名無しさん
垢版 |
2021/05/28(金) 06:24:24.88ID:Q2cy611+
>>39
> 2つの文字列リテラルの共通部分列の長さをコンパイル時定数として扱う
をやろうとして苦戦しています
再帰 constexpr 関数で計算しようと思ったんですが、引数として受け取った文字列リテラルの要素って定数と見なせないですよね?

そもそも無理か、勉強次第でできるかだけでも教えていただけたらありがたいです
0099デフォルトの名無しさん
垢版 |
2021/05/28(金) 12:14:40.97ID:sAi5WsuI
>>96
(a&)
の部分は、()は優先順位を変えているだけなので、コンパイラは
a&
という部分式を認識しようとする。しかし、a& という部分式は
C++では文法的に存在して無いのでエラーとなる。
単にそれだけの事。
0100デフォルトの名無しさん
垢版 |
2021/05/28(金) 12:22:24.96ID:sAi5WsuI
>>99
[補足]
C++コンパイラが
int x[N];      // (1)
というテキストをパースする際、コンパイラ内部では、
x --> [N] --> int
という順序の演算が並んでいると理解されている。そして、
int (&a)[N]     // (2)
というテキストをパースする時、優先順位括弧があるために、
(1)において、x を &a に置き換えたようにコンパイラは理解するなので、
数学の式変形での「代入」のように考えて、
&a --> [N] --> int   // (3)
のようになる。そしてさらに、&a は、a --> & のように式変形されるので、
(3) に安全のために優先順位の()を付けてそれを「代入」すると、
(a --> &) --> [N] --> int   // (4)
となる。しかし、この場合、優先順位の括弧ははずせるので、
a --> & --> [N] --> int   // (5)
となる。ここで、もとのテキストが、
int (a&)[N]     // (6)
だったならば、x が a& に相当することになるが、a& という部分式はC++には
存在しないので、そこでエラーになる。
0101デフォルトの名無しさん
垢版 |
2021/05/28(金) 12:48:09.21ID:sAi5WsuI
>>100
[さらに補足]
C++では、「宣言文」と地の文における「式」とは別扱いになっている。
なので、式における &a と宣言文における &a では、& の意味が異なる。
今回の場合は「宣言文」。
宣言文における &a は、a が参照型であることを意味する。
式における &a は、a のアドレスを取得する演算子である。

> x --> [N] --> int
> という順序の演算が並んでいると理解されている。

において「演算」と書いたのは、適切な言葉が見つからなかったため。
演算といっても、今回は宣言文ので、式における演算子とは意味が違う。
式に置いて x[y] は、常に *(x+y) と等価な演算子であるが、
宣言置いて x[N] は、演算子ではなく、x が N要素の配列型であることを
意味しているだけである。
また、最後の xxx --> int も演算子ではなく、型指定部と呼ばれ、
xxx の部分が int 型であるということを意味しているだけである。

しかし、コンパイラ内部では、
x --> [N] --> int
のように意味解釈がされていることだけは確かである。
■ このスレッドは過去ログ倉庫に格納されています

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