1 名前:sage [2022/10/31(月) 14:29:35.57 ID:J5sgTSch0.net] !extend:checked:vvvvv:1000:512 !extend:checked:vvvvv:1000:512 ↑同じ内容を3行貼り付けること 次スレは>>980 が立てること 無理なら細かく安価指定 ※前スレ C++相談室 part161 https://mevius.5ch.net/test/read.cgi/tech/1653135809/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
52 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 22:22:55.08 ID:XJxScCwYM.net] 2ch/5chでレベルが高い質問をすると、バッシングを受ける傾向が有ります。
53 名前:デフォルトの名無しさん [2022/11/10(木) 22:23:43.35 ID:xu9+brpFp.net] 頭が良い人なら、馬鹿にも分かる説明も難なくこなすんだがなぁ 自称してるだけの馬鹿なら意味不明な話を相手の理解力のせいにするんだよなぁ
54 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 22:25:12.06 ID:XJxScCwYM.net] >>45 例えば、class定義の中身Xが同じでも、class A {X} と class B {X} では別の型です。 その意味で、型が決まってないのです。 繰り返しますが、あなたはC言語の基礎が理解出来てないか、または、IQが この質問に対して足りてない可能性があります。
55 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 22:26:30.44 ID:XJxScCwYM.net] >>52 逆も有ります。 ちなみに、私は実世界で天才だと言われたことが何度も有ります。
56 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 22:29:41.43 ID:XJxScCwYM.net] >>53 [補足] {"aaa",1234}は、>>28 のEntryとよく似た方では有りますが、コンパイラ内部では Entryとは認識されません。仮に、 struct EntryB { const char *name, int number; }; とすれば、{"aaa",1234}は、中身の型としてはEntryBと全く同じと言えますが、 EntryBではないのです。 これが理解できないならば、C言語の基礎が理解出来てないので、質問の 意味が理解できないでしょう。
57 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 22:34:40.81 ID:XJxScCwYM.net] なお、数学的な言葉に慣れてない人は私の質問が哲学的な抽象論の様に聞こえて 頭が悪い人が変なことをいっているように聞こえたかも知れません。
58 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 23:38:43.51 ID:lrIHTbD+0.net] >>53 >例えば、class定義の中身Xが同じでも、class A {X} と class B {X} では別の型です。 nominal typing な世界ではたしかにAとBは別の型だが無名の{X}はAとBどちらにも一致する。
59 名前:デフォルトの名無しさん mailto:sage [2022/11/10(木) 23:56:40.35 ID:QHBEGLKOa.net] >>54 最近は体調どうよ
60 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:01:29.20 ID:J8vKnsQy0.net] あー君が何を勘違いしてるのか分かってきた 「初期化子`{"aaa",1234}`の型」というものがあると勘違いしてるんだな こいつは「const char*とintの要素が並んだ波括弧初期化子」であってこれ全体が型を持ってるわけじゃない あくまで「Entryを初期化(暗黙変換)出来る初期化子」「EntryBを初期化出来る初期化子」でしかなくて、これ自体をEntryとかEntryBとかそのものだと思いこんでるのが君の根本的な間違いだ (関数呼び出しfoo(1,2);の(1,2)だけ取り出してこの型は何だ?と聞いてるのと同じようなものでナンセンス) 初期化子の仕事はあくまで初期化なんだから、同じ文字列の初期化子でもその初期化対象の型(が許している初期化方法)によって意味は変わる Entryのようにstringとintを持った構造体なら集成体初期化になるし、 (const char*, int)の引数を取るコンストラクタ(非explicit)の呼び出しにもなるし、 initializer_list<Foo>(Fooはconst char* とintの両方から暗黙変換できる型)にもなれる なれるというか、初期化対象型のコンストラクタオーバーロードに対して一番適合するものを探し出す(無理ならエラーにする)のがコンパイラの仕事で、当然全部静的に決まるようになってる こういう風に同じ波括弧にいろんな解釈方法を持たせることで初期化を柔軟に書けるようになってるわけだ(C++11で導入されたuniform initialization) キチガイみたいだから優しく教えるのはこれで最後にする すまんかったね
61 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:16:31.96 ID:NMTpQElqM.net] >>59 型を持ってるわけじゃないのは当然なのに、あなたが「動的型」というこっちが 言ってないことを勝手に妄想しだしたので、基礎から解説したまでです。 こっちの方が圧倒的に頭がいいので、食い違うのです。
62 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:17:28.31 ID:NMTpQElqM.net] 馬鹿は自分が馬鹿だと気付かないんです。 質問の意味すら分かってないのに質問に答えようとしてくる。
63 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:22:09.88 ID:NMTpQElqM.net] >>59 このような場合にC++では型が静的に決まるのは当たり前。 あなたこそ、動的言語を前提にしているように思える。 そういうことではなくて、コンパイラが内部でどのような順序で「静的に」翻訳作業を 行なっているかを質問している。 コンパイラ内部では型を持って無くても、構文ツリーや色々な形でデータを 持っているが、仕様では、その順序までも決まってないとコンパイラで非互換性が 出てきてしまうし、何より、C++では演算子のオーバーロードなども出来る訳 だから、コンパイラの内部的な解釈の順序まで厳密に仕様化されてなければ、 一般プログラマも混乱が生じる。 その事を聞いている。
64 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:26:17.38 ID:NMTpQElqM.net] >>62 [補足] JSなどの動的で初心者ならば、「大体」で理解していればそれで問題無い事が 多いだろうが、C++では、テンプレートもあればoperator+()演算子や型変換 演算子などをオーバーロードできるから、「大体」では駄目で、非常に細かな コンパイルの順序や解釈の流れまでが言語の仕様書に厳密に書いてなければ 正しいアプリケーションコードを書くことが出来ないことがある。 「直感的に簡単に理解できるのに、何この馬鹿は聞いているんだ?」 などと思っているとすれば、大間違いだ。
65 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:28:53.35 ID:L/uUC/Rw0.net] 質問はしたのだから、回答を待っていればいいだろうに 何でまた独り言を延々と書いてるのか、不思議だ 書くなら自分の日記帳に書けばいいのでは
66 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:32:42.01 ID:NMTpQElqM.net] >>63 [補足] >>28 で、phone_bookの初期化子について、「直感的に」理解できたら それで十分、などと考えている人は、馬鹿なので質問には答えないで下さい。 C++コンパイラは、そのように大体で動作しているのではなく、パターン に当てはめて順序を追ってコンパイルを進めていきますが、その順序や 解釈の仕方がC++03の時代とはかなり違っているように思えたから 質問したのです。 例えば、>>28 は単なる例であって、これの応用として非常に複雑なコードを 書いた場合でも、コンパイラはなんたかの単純な法則に従って厳密に翻訳していきます。 その正確な規則が分からないから聞いているのです。
67 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:33:22.29 ID:NMTpQElqM.net] >>64 馬鹿な人が茶々入れしてきたので、排除する努力をしています。
68 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:40:51.17 ID:NMTpQElqM.net] >>59 >Entryのようにstringとintを持った構造体なら集成体初期化になるし、 今回の例では、vector<Entry>型の初期化ですので、そんな単純ではありません。 vector<T,A>テンプレートのコンストラクタが呼び出されるはずです。 しかも、コンストラクタの種類が沢山ありますから、それを選ばなくてはなりません。 Entry a = {"xxx",1234}; ならば集成体初期化ですから、コンストラクタを選ぶ工程は無いはずですから、 比較的単純です。 ところが、今回の場合は、コンストラクタの選択から始まります。 しかし、初期化子自体の型が中途半端な状態でコンストラクタを選ぶ必要が ありそうなので質問しているのです。 C++03で、x+y書いた場合、xとyの型が決まった後で、operator+(U,T)演算子を探します。 ところが今回の場合、初期化子の部分の型が中途半端な状態なので、コンストラクタを探す ための手がかりが中途半端にしかないのです。
69 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:45:48.11 ID:NMTpQElqM.net] >>67 [補足] CPerson person{"Suzuki", 25}; と書いた場合、CPersonのコンストラクタはすぐ探せます。 ところが、>>28 のように vector<Entry> phone_book = { {"David Hyme",123456}, {"Karl Popper",234567}, {"Bertrand Arthur William Russell",2345678} }; の場合、テンプレート vector<T,A> の中のコンストラクタを選ぼうとしても、 初期化子の{"David Hyme",123456}には、ある意味では「型が存在してない」ので 通常のように探すことは出来ないのです。
70 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:48:44.75 ID:J8vKnsQy0.net] >>65 正確な規則が知りたいのに規格に当たることすら思いつかないのか自称天才のボンクラ様ってのは 9.4 Initializers [dcl.init](C++20公開ドラフトN4861、正規の規格がいいなら自分で買え)を見ればいいよ 誰でも読めば分かるように書いてある規格を天才様が理解できないなんてありえないから以降質問禁止な
71 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:55:21.61 ID:NMTpQElqM.net] >>68 [補足] vectorは配列と似ていますが、コンパイラの内部的にはかなり違う扱いになっていて、 Entry a[3] = { {"David Hyme",123456}, {"Karl Popper",234567}, {"Bertrand Arthur William Russell",2345678} }; と書いたならば、コンパイルの翻訳過程は全く異なってきます。 この場合はとても単純で、 T a[N] = {XXX}; の形式は、配列初期化として特別処理されています。 なので、コンストラクタを探す工程、というものが必要ありません。 そして、{"David Hyme",123456} の型を知る必要も無く、単純に、 Entryのメンバに代入していくような処理となります。 この場合の処理は、まず最初に配列型として処理が入り、次にEntryの構造体型 としての処理が入ります。 これが理解できない人は質問には答えないで下さい。混乱の元になります。
72 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:56:13.87 ID:NMTpQElqM.net] >>69 そんな言い方されれば質問サイトの意味が無いわけです。
73 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 00:59:02.50 ID:J8vKnsQy0.net] >>68 あまりにも馬鹿すぎて哀れだからもう1回だけ助け舟出してやる いいか?vector<Entry>がどんなコンストラクタ持ってるか(どうオーバーロードされてるか)は決まってんだよ vectorテンプレートを実体化した時点で静的に全部決まってんだよ 馬鹿なお前だって<vector>ヘッダを隅々まで読めば列挙くらい出来るのは分かるだろ vector<Entry>のコンストラクタは例えばvector<Entry>()とかvector<Entry>(size_type)とかvector<Entry>(vector<Entry>&&)とかvector<Entry>(initilaizer_list<Entry>)とか色々あるわけだな(全部は挙げんぞ) コンパイラ様はまずそれを列挙するわけだ。そして ・vector<Entry>()かな?→空じゃないからダメ ・vector<Entry>(size_type)かな?→{...}はsize_typeに変換できるかな?→ダメ ・vector<Entry>(vector<Entry>&&)かな?→{...}はvector<Entry>&&に変換できるかな?→ダメ ・vector<Entry>(initilaizer_list<Entry>)かな?→{...}はinitilaizer_list<Entry>に変換できるかな?→OK! ・... ってひたすら一つずつ試すわけだ。で、vector<Entry>(initilaizer_list<Entry>)しか当てはまるものがないので、じゃあこれだとオーバーロードを解決するわけだ コンパイラのやってることなんて基本的にこれだけだ、実に単純な話だ こんな単純なこともわからずグチグチグチグチとお前は本当に無能だな
74 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:02:30.49 ID:NMTpQElqM.net] >>72 その探し方は、普通の関数のオーバーロード解決とは異なっていますね。 しかも、あなたの言っているほど単純じゃない。 実際は、優先順位があり、先に優先順位の低いものが見つかって、後から 優先順位が高いものが見つかっても、後の方が優先される。 あなたが馬鹿なのは、単純に考えすぎていることだ。
75 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:03:31.20 ID:J8vKnsQy0.net] >>71 なんで答えが書かれた文書が誰でも読めるように公開されてるのに、わざわざ自分より劣った人間に答えを求めるの? お前天才なんだろ?ここの誰よりも賢いんだろ? 消えな
76 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:04:06.86 ID:hvQf6BDd0.net] >>74 すまんがお前が消えてほしい 相手するからつけあがる
77 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:05:05.21 ID:NMTpQElqM.net] >>73 [補足] なお、関数のオーバーロード解決でも、「変換できるかどうか」とかそんな単純な ものじゃないです。 例えば、T a{x} のように{}が書いてあれば、中味が1個しか書いてなくても、 initializer_list が優先される、などと決まってます。
78 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:05:24.11 ID:J8vKnsQy0.net] >>73 だから正確なのが知りたいなら規格読めやボケカス お前のゴミ虫みたいな脳みそに合わせてわざわざ単純化してやったのに何だその物言いは無礼者の恥知らずが
79 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:06:38.58 ID:NMTpQElqM.net] >>74 俺よりC++を知っている人だってこの世にいるから質問してる。 それでは質問サイトの意味がない。 調べればわかることでも知ってる人に聞いたほうが早い。
80 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:07:31.06 ID:J8vKnsQy0.net] >>76 T a{x}ってそれ関数じゃなくて変数定義ですよ そんな区別もつかないレベルじゃ規格書なんて早かったかなごめんね でもそれも規格書に書いてあるから読んで勉強しろ
81 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:07:50.72 ID:NMTpQElqM.net] >>77 あなたみたいなのが日本を衰退させている。 自分が頭がいいと思い込んでいるがかなり間違ってるし、レベルが低い。 そして、あなたの周りにはレベルの低い人しか回りに居ないから勘違いが 直らない。
82 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:08:28.22 ID:NMTpQElqM.net] >>79 アホですか。 コンストラクタを探す話をしている。
83 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:09:07.49 ID:J8vKnsQy0.net] >>78 ここで俺や他の人が説明してあげてる内容すら理解できないなら、規格書を泣きながら読むか死んだほうが早いと思うよ
84 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:10:04.92 ID:NMTpQElqM.net] 日本は分断化が激しい社会だ。 カシコが一部に集まり、アホがあほ同士集まっている。 だから自覚できない。 そういう社会にしてしまっていることが問題。
85 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:10:52.44 ID:J8vKnsQy0.net] >>81 1行目のせいで関数のオーバーロード解決の話をしてるもんだと思ったよ どうやらC++以前に日本語すら不自由なようだね
86 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:11:25.32 ID:NMTpQElqM.net] >>82 お前は理解できてないのに質問に答えようとしている。 いつもは質問のレベルが低いから答えられているんだろうが、今回は お前の能力を超えている。 そしていつもの調子で質問者をレベルが低いと思い込んでいるから 馬鹿にした態度をとる。
87 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:11:57.99 ID:NMTpQElqM.net] >>84 お前に言われたくない。
88 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:14:33.80 ID:NMTpQElqM.net] >>82 「してあげている」 って、おまえの思ってる直感的理解と、俺の求めている理解とは次元が違う。 お前は、いっぱんぴーぽーとしてC++を使えてもそれ以上はできないだろう。
89 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 01:16:18.16 ID:J8vKnsQy0.net] もう終わりにするけど、俺の説明が間違ってるって言うならそれは規格と主要コンパイラの実装が間違ってるってことだから ISOとベンダーに報告しときなよ >>75 ごめんなさいみなさん久しぶりに面白いおもちゃだったのでつい
90 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 02:19:52.16 ID:tp0srwYgd.net] キャラ剥がれてきてて草
91 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 05:29:55.03 ID:wl59B58M0.net] std::array<T, N>って「N個の値xで埋める」コンストラクタありませんよね? 後でstd::fillするのが普通のやり方かもしれませんが、実際はstd::arrayのインスタンスができた時点でN個の何らかの初期値が入るんですよね? この仕様に困ってます。 例えば、boost::multi_arrayは構築時にメモリの並び方 (Cライク or fortranライク) が決まって、後で変更する方法は提供されてないんですが、 std::array<boost::multiarray, N> を作ってしまうとメモリの並び方が勝手に決まってしまいます。 std::array の各要素のコンストラクタをこちらで呼ぶ方法があったら教えてください。 初期化リストで構築するやり方はNが大きいときは現実的でないので考えておりません。
92 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 07:32:36.01 ID:fbtAWiSRH.net] >>54 逆はないと思いますよ
93 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 07:44:40.78 ID:J8vKnsQy0.net] >>90 残念ながらarrayで初期化時にやるのは無理 arrayは組み込み配列と同じ初期化方法(集成体初期化)しか出来ないように意図的に設計されてて特別なコンストラクタを持たない だからarray::fill()が用意されてるので普通はそれを使う どうしてもその場で要素のコンストラクタを直接呼びたいなら一回構築してから要素ごとにデストラクタ→placement newを呼ぶしかない 最初のデフォルト構築も許せないならarray(と組み込み配列)を使うのは諦めよう
94 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 15:28:43.83 ID:x9X8FiGQM.net] >>91 いくらアインシュタインが相対性理論を説明しても、一般人には理解できない。 どんなに天才でも、説明できない事柄がある。
95 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 19:19:22.94 ID:+I+8FBiLd.net] 天才ほど説明が下手だね 天賦の才に頼らず這い上がった苦労人タイプの 説明のほうが一般人には分かりやすい
96 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 20:11:09.74 ID:MfyOP1HR0.net] わかった気になるだけってやつね 完全に理解する必要のない一般人ならそれもあり
97 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 20:47:56.26 ID:76yLxZ0B0.net] 誰かを見下していなきゃ自分を保てない小さいやつ
98 名前:デフォルトの名無しさん mailto:sage [2022/11/11(金) 23:42:57.00 ID:jawQM+EmM.net] 確かに右辺値参照あたりの仕組みはコピー減らそうという意図が感じられる割に徹底しようとするとstd::arrayとかのctorで足元すくわれがち
99 名前:デフォルトの名無しさん (ワッチョイ 7501-WFXv) mailto:sage [2022/11/12(土) 01:01:47.32 ID:0JLM8m+J0.net] ワッチョイつけると炎上しなくて良いね
100 名前:デフォルトの名無しさん mailto:sage [2022/11/12(土) 07:48:03.70 ID:GOjTxZ8j0.net] arrayは組み込み配列の糞さ緩和が目的なので糞が多少まろび出るのは仕方ないんよね
101 名前:デフォルトの名無しさん mailto:sage [2022/11/12(土) 09:59:28.06 ID:D5o/xiXJ0.net] >>92 collectionで初期化も無理なんだ? せめてvectorで初期化できるなら良かったのにね
102 名前:デフォルトの名無しさん mailto:sage [2022/11/12(土) 11:30:02.52 ID:GOjTxZ8j0.net] 1つでもコンストラクタを独自定義したら集成体になれないので仕方ない
103 名前:はちみつ餃子 mailto:sage [2022/11/12(土) 14:25:39.92 ID:5guAadWy0.net] >>90 要素のデフォルトコンストラクタは呼ばれるので要素のほうに適当なラッパーを被せるという方法はとれなくはない。 こういうラッパーならスタンダードレイアウトの要件は満たすのでバイト列レベルでも互換性は維持されるはず。 #include <array> #include <iostream> struct foo { // このコンストラクタを呼んで欲しい foo(int x){ std::cout << x << std::endl; } }; template <class T, auto N> struct initializing_wrapper : public T { initializing_wrapper(void) : T(N) {} }; int main() { std::array<initializing_wrapper<foo, 1> , 3> foo; }
104 名前:デフォルトの名無しさん mailto:sage [2022/11/12(土) 23:48:04.66 ID:2iksiTkL0.net] vscodeでeigen使ったコード書いてるんだけど、デバッグ時にeigenの変数見る方法ある? visualstudioならあるっぽいんだけど、vscode上でしょりした
105 名前:「んだよね [] [ここ壊れてます]
106 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 00:14:31.39 ID:5VmZbZRR0.net] 普通に変数ウォッチで見えんの?
107 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 04:06:31.61 ID:L3LR+iGt0.net] ちょ、何これ? 聞いてないんだけど。。。 C:/msys64/mingw64/include/c++/12.2.0/bits/stl_pair.h:326:13: note: declared here 326 | pair& operator=(const pair&) = delete; C:/msys64/mingw64/include/c++/12.2.0/bits/stl_pair.h:715:5: note: declared here 715 | swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
108 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 07:39:53.36 ID:alAGhxI40.net] >>103 eigen一回も使ったことないしググってもないけど、行列の先頭要素のメモリにアクセスする方法が提供されてないわけないので、それを使う 普通はdata()とかget()なるメンバ関数がある
109 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 11:52:46.36 ID:7rETCoZw0.net] >>105 -std= で規格を指定するとか?
110 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 12:42:20.71 ID:JmrIg+tw0.net] -std=c++20にしてる
111 名前:はちみつ餃子 mailto:sage [2022/11/13(日) 14:31:41.33 ID:sejtbDAm0.net] >>105 本来使われるはずの定義はこっち。 https://github.com/gcc-mirror/gcc/blob/e24b430f1ea60205162fd9b327ac6a4dfc57f37c/libstdc%2B%2B-v3/include/bits/stl_pair.h#L371-L379 必要な性質 (要素の型が copy_assignable) が満たされていないときに最も優先度が低いやつが選択された上でそれが delete されているということになるんだと思う。 https://github.com/gcc-mirror/gcc/blob/e24b430f1ea60205162fd9b327ac6a4dfc57f37c/libstdc%2B%2B-v3/include/bits/stl_pair.h#L368
112 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 16:56:29.94 ID:L3LR+iGt0.net] 壮大なSFINAEってわけか・・・ 元コードは晒せないんであとは自分で探すしかないな ヒントありがと、餃子さん
113 名前:はちみつ餃子 mailto:sage [2022/11/13(日) 18:18:04.90 ID:sejtbDAm0.net] どうせ使えないなら使おうとしたときに static_assert で問題点を出すようにしたらいいのにと思ったがよく考えるとそれは駄目なんだな。 適用できるものがないということを SFINAE のトリックに使うことがあるかもしれない。 (static_assert が展開されると他の候補があっても問答無用で終わりになってしまう。)
114 名前:デフォルトの名無しさん mailto:sage [2022/11/13(日) 18:23:28.51 ID:BN7kyEsvM.net] いつもサナエさんにはお世話になってる
115 名前:デフォルトの名無しさん (アウアウウー Saa9-FFna) [2022/11/14(月) 12:10:20.06 ID:EWF0SvAna.net] >>94-95 天才とパンピーで理解レベルのバックグラウンド知識に差があるからだろ その差を埋める説明を一瞬で出来る人はそれなりの才能があるとは思うが 天才同士ならそんな説明いちいちしなくても判り合えるんだ
116 名前:デフォルトの名無しさん (スップ Sd03-3Wva) mailto:sage [2022/11/14(月) 19:05:49.95 ID:KWfGC8qSd.net] 天才はそもそも他人の説明なんかいらんからな
117 名前:デフォルトの名無しさん mailto:sage [2022/11/14(月) 22:27:38.95 ID:sRgsAS70H.net] 自分が天才だ!とわざわざ自称しなくても、天才らしい雰囲気をかもし出せるレスはないものでしょうかね… 自称天才はもういいし
118 名前:デフォルトの名無しさん mailto:sage [2022/11/14(月) 22:42:37.02 ID:rM2EwItV0.net] ギフテッドって凄すぎて訳わからんからな
119 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 12:36:06.45 ID:+zOZoQ9YM.net] プログラミング言語 C++ [第四版], 日本語訳 の p.689 に、 template<typename T> class Xref { ・・・ }; template<typename TT, typename A> unique_ptr<TT> make_unique(int i, A&& a) { return unique_ptr<TT>{new TT{i,forward<A>(a)}}; } auto p1 = make_unique<Xref<String>>(7,"Here"); 「ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&) が呼び出される。」 とありますが、実引数の文字列リテラル "Here" が、make_unique()の 仮引数 A&& に渡そうとしたら、A = string と「演繹」されているようですが、 const char* 型が string に至るまでの仕組みか分かりません。 どなたが分かる人居ませんか? 実際の STL の sting は basic_string<U> テンプレートの U=charの 場合だと思われますが、意味を概念的に言えば、 class string { public // 変換コンストラクタ : string(const char *) {・・・} }; という「変換コンストラクタ」があるでしょうから、それが使われている ことは推定は出来ます。 しかし、上記のテンプレートで T を演繹する際に、このような変換コンストラクタ が呼び出されるメカニズムが分かりません(仕様書のどこに書いてあるのかが 分からない。)。
120 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 12:51:05.19 ID:+zOZoQ9YM.net] >>117 もっと詳しく書くと、直前から次のように書かれています: # Xref<String>はXref<string>の写し間違いでした。 string x {"There and back again"}; template <typename T> T&& std::forward(typename remove_reference<T>::type& t) noexcept; template <typename T> T&& std::forward(typename remove_reference<T>::type&& t) noexcept; ここで望まれるのは、不純なコピーを一切作ることなく、 make_unique<T>(arg)がargからTを構築することである。 その実現には左辺値と右辺値の区別を管理することが重要だ。 次の例を考えてみよう: template<typename TT, typename A> unique_ptr<TT> make_unique(int i, A&& a) // make_sharedのちょっとした変種 { return unique_ptr<TT>{new TT{i,forward<A>(a)}}; } auto p1 = make_unique<Xref<string>>(7,"Here"); ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&) が呼び出される。 そして、"Here"を格納しているstringのムーブを行なうために、 Xref(int,string&&)が呼び出されることになる。 # 個人の感想: これは、A=stringと考えられます。 もっと興味深い(しかも分かりにくい)のが、次のものだ: auto p2 = make_unique<Xref<string>>(9,x); ここで、xが左辺値なので、左辺値を引数にforward(string&)が呼び出される。 forward()のTは、string& と導出される。そのため、返却値は string & &&となる。 もちろんそれは string & を意味する(§7.7.3)。その結果、左辺のxに対して、 Xref(int,string&)が呼び出されて、xがコピーされる。 # 個人の感想: これは、A=string&と考えられます。
121 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 12:53:27.82 ID:+zOZoQ9YM.net] >>118 [参考] p.724, 「文字列リテラルは、テンプレート引数には『渡せない』」 ただし、これがどう関係しているのかは不明です。 A&& a の部分に文字列リテラル"Here"を渡してはいますが。
122 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 12:56:01.43 ID:f326q+3ca.net] ある型が来たらそれに応じた変換をするのが、何か問題なんでしょうか
123 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 12:57:17.27 ID:slZuGS0Ed.net] make_uniqueの実体化の所でTT=Xref<String>、T=Stringって明示的に指定してるじゃん 「演繹」なんかするまでもないから規格に書いてるはずもない 天才のくせにそんな事も分からないの?
124 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 13:00:23.02 ID:+zOZoQ9YM.net] >>119 [ヒント] 前頁p.688の下段: 「左辺値と右辺値は、テンプレート引数の導出では区別される。 X型の左辺値はX&として導出されて、右辺値はXとして導出される。 これは、非テンプレート引数の右辺値参照への値のバインド (§12.2.1)とは異なる。 しかし、引数転送(§35.5.1)においては、極めて有用だ。 Xrefを空き領域上に置いて、そのポインタをunique_ptrとして 返すファクトリ関数を記述する場合を考えてみよう: 」 の直後、ページが変わってページの最初に>>118 の std::forward テンプレート の定義が書いて有ります。
125 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 13:02:34.01 ID:slZuGS0Ed.net] 引用の範囲超えてるんで著作権侵害の疑いで削除依頼出しますね
126 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 13:03:00.86 ID:+zOZoQ9YM.net] >>121 TTは、Xref<string>と明示的に指定されてますが、AはTTとの関係は 書いて無いはずです。 なので、それだけでは、A=stringとは分からないはずでは。
127 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 14:16:43.16 ID:D78/LkiC0.net] new TT{i, forward<A>(a)} 既出だが、こう書いてあってもXrefのメンバの型がどうなるか分からんわけでしょ 先日の質問と合わせて、型パズルをスラスラ解けるような資質がない 資質がないんでXrefの『関係ない』としたところを「・・・」で埋めてる
128 名前:はちみつ餃子 mailto:sage [2022/11/15(火) 15:01:57.79 ID:5Bng48RE0.net] >>117 どういう文脈で説明されてるのかよくわからんが 引数が文字列リテラルの "Here" なら A は const char (&)[5] に推論されるよ。
129 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 16:18:06.60 ID:Q+AZCxhHM.net] >>126 命題『A が const char (&)[5] に推論される』・・・☆ とし、背理法で考えます。 ☆が正しいと仮定すると、 forward<A>(a)は、forward<const char (&)[5]>(a)となりますが、すると、 template <typename T> T&& std::forward(typename remove_reference<T>::type& t) noexcept; template <typename T> T&& std::forward(typename remove_reference<T>::type&& t) noexcept; に対して、forward<const char (&)[5]>(a) が呼び出されることになります。 しかし、 >auto p1 = make_unique<Xref<string>>(7,"Here"); >ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&) >が呼び出される。 とBJ stroustrup氏が書いています。 ならば、T=const char (&)[5]の時に、 typename remove_reference<T>::type がstringにならなければなりません。つまり、 typename remove_reference<const char (&)[5]>::type がstringになってないと矛盾する事になります。 もし、矛盾するならば、背理法により、☆は否定されることになります。 (矛盾しそうです。)
130 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 16:42:50.09 ID:Q+AZCxhHM.net] >>127 これは背理法とは言わなかったわ。 スマソ
131 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 16:49:22.19 ID:f326q+3ca.net] メロスはポリモーフィズムがわからない
132 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 17:18:50.72 ID:eijjsxUX0.net] Perfumeの楽曲だろ?
133 名前:はちみつ餃子 mailto:sage [2022/11/15(火) 18:04:53.44 ID:5Bng48RE0.net] >>127 > ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&) > が呼び出される。 文字列リテラルは左辺値。 右辺値だと書いてあるのならそれが間違っている。 配列がポインタに (暗黙的でも明示的でも) キャストされる文脈では そのポインタは xvalue (おおよそ右辺値のような扱いになる分類) になるが、 今回は変換が入らずに参照で受けているのでそうはならない。 /// この場合は rvalue 扱い #include <cstdio> void foo(const char *&x) { std::printf("lvalue"); } void foo(const char *&&x) { std::printf("rvalue"); } int main(void) { foo("abc"); } /// この場合は lvalue 扱い #include <cstdio> template <class T> void foo(const T &x) { std::printf("lvalue"); } template <class T> void foo(const T &&x) { std::printf("rvalue"); } int main(void) { foo("abc"); }
134 名前:デフォルトの名無しさん [2022/11/15(火) 18:53:35.18 ID:mUSyU2rD0.net] 文字列リテラルが左辺値ってなんで?
135 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 20:56:02.85 ID:aOXxipO5M.net] 文字列リテラルは実際は配列 ⇒アドレスで区別できるメモリ上のオブジェクト ⇒つまりlvalue
136 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 20:56:58.78 ID:kbPjYi7D0.net] 文字列リテラルはメモリ上に永続的に保持されるんだから勝手に持ってっちゃダメでしょ
137 名前:デフォルトの名無しさん mailto:sage [2022/11/15(火) 21:11:40.64 ID:DJ4SZBHq0.net] 文字列リテラルは配列型のlvalue 文字列リテラルが左辺値変形されて生じたポインタはrvalue
138 名前:はちみつ餃子 mailto:sage [2022/11/15(火) 23:54:26.84 ID:5Bng48RE0.net] 配列 (文字列を含む) と関数は値として扱えない、勝手にポインタに型変換するという C から引き継いだ変則的なルールに辻褄を合わせているので全体的に変則的で 分かりにくいんだよ……。
139 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:19:44.88 ID:g3O9ReAZM.net] >>131 >auto p1 = make_unique<Xref<string>>(7,"Here"); >ここで、"Here"は右辺値なので、右辺値を引数にしてforward(string&&) >が呼び出される。 と書かれています。 なので、"Here"がなんらかのメカニズムでstd::stringに変換されていると 解釈しました。 実験すれば白黒はっきりさせることが出来るかも知れません。
140 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:20:20.66 ID:DtzZSdSg0.net] マジで間違った方向に引きずり回してんのか やっぱりすげーな こいつは上級者だ
141 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:29:08.01 ID:g3O9ReAZM.net] >>138 C++の父であるところのBJ Stroustrup氏が直々に書いて
142 名前:「ることなのですが。 [] [ここ壊れてます]
143 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:32:07.57 ID:Nbbm6FAB0.net] 禿本手元にないから確認はできないけど、「"Here"が右辺値」なんて基本的な間違い書くとは思えないんだけど 侵害くんの読み間違いか書き間違いか、本当に書いてあるなら翻訳ミスじゃないの
144 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:32:57.76 ID:Nbbm6FAB0.net] >>139 "Here"の配列→(配列とポインタの糞ルール)→const char*→(stringの変換コンストラクタ)→string と変換された結果のstring一時オブジェクトが右辺値だってクドクド書いてない?ちゃんと読んだ?
145 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:38:01.28 ID:g3O9ReAZM.net] 原書(英語版)はこうなってます: 23.5.2.1. Reference Deduction ... template<typename T> class Xref { public: Xref(int i, T* p) // store a pointer: Xref is the owner :index{i}, elem{p}, owner{true} {} Xref(int i, T& r) // store a pointer to r, owned by someone else :index{i}, elem{&r}, owner{false} {} Xref(int i, T&& r) // move r into Xref, Xref is the owner :index{i}, elem{new T{move(r)}}, owner{true} {} ~Xref() { if(owned) delete elem; } //... private: int index; T* elem; bool owned; }; ...
146 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:38:41.12 ID:g3O9ReAZM.net] >>142 template<typename T> T&& std::forward(typename remove_reference<T>::type& t) noexcept; //§35.5.1 template<typename T> T&& std::forward(typename remove_reference<T>::type&& t) noexcept; template<typename TT, typename A> unique_ptr<TT> make_unique(int i, A&& a) // simple variant of make_shared (§34.3.2) { return unique_ptr<TT>{new TT{i,forward<A>(a)}}; } We want make_unique<T>(arg) to construct a T from an arg without making any spurious copies. To do that, it is essential that the lvalue/rvalue distinction is maintained. Consider: auto p1 = make_unique<Xref<string>>(7,"Here"); "Here" is an rvalue, so forward(string&&) is called, passing along an rvalue, so that Xref(int,string&&) is called to move from the string holding "Here". The more interesting (subtle) case is: auto p2 = make_unique<Xref<string>>(9,x); Here, x is an lvalue, so forward(string&) is called, passing along an lvalue: forward()’s T is deduced to string& so that the return value becomes string& &&, which means string& (§7.7.3). Thus, Xref(int,string&) is called for the lvalue x, so that x is copied. Stroustrup, Bjarne. The C++ Programming Language (p.689). Pearson Education. Kindle 版.
147 名前:デフォルトの名無しさん [2022/11/16(水) 00:40:39.32 ID:85X5ndMu0.net] C++ど素人なんですが、この画像のようなファイル群がある時に、Visual Studioでexe化するにはどうしたら良いですか? まず、ファイルはsln形式などになってないですが、そういったものはつくる必要はなく、ExpressionApp.cppだけ開いてビルドボタンを押したりすれば良い感じなのでしょうか?
148 名前:デフォルトの名無しさん [2022/11/16(水) 00:41:05.14 ID:85X5ndMu0.net] >>144 すみません、画像を貼り忘れました https://i.imgur.com/zn41rYL.png
149 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:41:14.43 ID:Nbbm6FAB0.net] えぇ…禿さん耄碌してんなあ
150 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:41:57.33 ID:Nbbm6FAB0.net] >>145 cmake使え
151 名前:デフォルトの名無しさん mailto:saeg [2022/11/16(水) 00:42:22.40 ID:g3O9ReAZM.net] >>140 "Here" is an rvalue, so forward(string&&) is called, passing along an rvalue, so that Xref(int,string&&) is called to move from the string holding "Here". >>141 テンプレート関数なので、Aという方引数が決定されるメカニズムが重要となります。 Aがstringに決定されたならば、文字列リテラルからstringへの変換法則はおなじみの ものとなります。 それよりも、まず、どうしてAがstringに決定されたのかの「仕組み」が分かりません。
152 名前:デフォルトの名無しさん mailto:sage [2022/11/16(水) 00:44:42.87 ID:P8Ivr6rPa.net] >>144 プロジェクト作ればいいよ