X



C++相談室 part146

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん
垢版 |
2019/11/07(木) 11:35:36.76ID:4wggfTwe
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part145
http://mevius.5ch.net/test/read.cgi/tech/1568362404/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
0862846
垢版 |
2019/12/14(土) 10:35:10.86ID:QUVSvjZy
>>854
>診断メッセージをよく見ろよ
見た上で言ってます(つまりgccまたはVC, clangのバグではないかということ

>いいか、constexprは翻訳時定数だぞ
それ以前にテンプレートなんですが
0863デフォルトの名無しさん
垢版 |
2019/12/14(土) 12:26:05.30ID:m0rD8Ode
ローマ法王は根競べで決めるらしいですよ奥さん。
0864デフォルトの名無しさん
垢版 |
2019/12/14(土) 12:26:49.81ID:gw9aL+td
誰でも閲覧できる規格ドラフト見ればすぐにわかることをこんな掃きだめで聞いても
0865デフォルトの名無しさん
垢版 |
2019/12/14(土) 12:35:13.30ID:SZLGcxYz
>>862
なんかとんがってんな

コンパイラのバグとまで言う根拠は何だ?
相場では規格票の条文だが

テンプレートなのは見ればわかるさ
だから何なのか説明をやめないでくれ
0867デフォルトの名無しさん
垢版 |
2019/12/14(土) 12:58:43.25ID:m0rD8Ode
これODRの緩和と関係あるんですかね?
0868デフォルトの名無しさん
垢版 |
2019/12/14(土) 13:34:08.27ID:T/HCOnVQ
>>772
>x86系CPUで普通のメモリへの読み書きで順番が入れ替わる可能性があるのは write => read だけ
別に。
コアAの読み書きをコアA自身が見る分にはそうかもわからんが
コアAの読み書きを異なるコアBから見たらwrite同士やread同士でも順番が入れ替わり得る
(アウトオブオーダー実行の影響で

安全に動かすには適切にメモリバリアで順序化する必要がある
0870デフォルトの名無しさん
垢版 |
2019/12/14(土) 13:37:51.96ID:T/HCOnVQ
といってもロックレス何ちゃらぐらいの制御であればInterlockedCompareExchange()で済むから
スレッド間の通信なら普通メモリバリアとか直接触る必要は無いが
0873デフォルトの名無しさん
垢版 |
2019/12/14(土) 13:39:40.59ID:T/HCOnVQ
リードキューやコマンドキューにコマンドが入るのはアウトオブオーダープロセスの事後であるため
そのような保証は無い
0876デフォルトの名無しさん
垢版 |
2019/12/14(土) 14:15:12.84ID:JwYnIOEa
x86系は
シングルコアのマルチスレッドアプリ
の多くがそのまま動くように出来てる

シングルコア時代が長かったから
0877デフォルトの名無しさん
垢版 |
2019/12/14(土) 14:55:10.15ID:QUVSvjZy
>>865
>テンプレートなのは見ればわかるさ
>だから何なのか
普通に考えて、実体化がまだなのに定義(初期化)を強制される妥当な理由はない、ということ
0878デフォルトの名無しさん
垢版 |
2019/12/14(土) 14:57:30.67ID:T/HCOnVQ
確かにリンク先のインテルのマニュアルの
>8.2.3.2 Neither Loads Nor Stores Are Reordered with Like Operations
>Example 8-2. Stores Are Not Reordered with Older Loads

>Initially x = y = 0r1 = 1 and r2 = 1 is not allowed
と書いてあって>>875と同じことが書いてあるが疑わしい
マニュアルが間違っているのではないか、

ちな
>8byteのデータはアドレスが8の倍数のときにアライメントされている。
から安全に読み書きできるというのはi486みたいな古いプロセッサーだとかえって危険らしい
>8.1.1 Guaranteed Atomic Operations
を見たらワカル、
0879デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:04:35.33ID:T/HCOnVQ
つか上のインテルのマニュアルには「投機的実行時中のメモリアクセスではメモリアクセス例外は発生しない」
旨が2箇所ぐらいに書かれているが、
ということはつまりアセンブリコード上A→BまたはA→Cというメモリアクセスが条件によってどちら片方だけ実行されることを意図したコードであっても
A→B→Cというメモリアクセス順に成り得ることを意味し、他コアからもそう見えてしまうはずだが、
これをメモリアクセス順がreorderされていないうちに入れてしまうのはどうなのか、、、
マニュアル執筆者の国語の再教育が必要なのではないか
0880デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:10:49.52ID:SZLGcxYz
>>877
おまえさん、もしかして
テンプレートの宣言と定義と
オブジェクトの宣言と定義を
ごっちゃにしてないか?

int test;
int test = 5;
これは宣言と定義じゃなく定義の重複だぞ
0881デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:13:40.23ID:PwUHvw+y
お前なぁ
x86のこと大して詳しくないのにしゃしゃり出てくるからそういう情けないこと言うはめになるんだよ
x86でstd::atomicのmemory_orderを変えてバリア付きがどういうインストラクションになるか見てみな
storeのseq_cst以外は素のmovだから(コンパイラ依存だから絶対ではない)
0882デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:20:09.00ID:T/HCOnVQ
そりゃー間違ったマニュアルにしたがって実装したら間違った実装になり得る(キリ

ていうかアウトオブオーダー実行の影響がマルチコアCPUにおいても透過的だと認めやっても良いが、
>>879の投機的実行の件はどうなんじゃ?
あるコアが投機的実行中に他のコアをストップさせるのでは何のための投機的実行かわからん…
0883デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:21:14.95ID:k5kIl1RN
>>877
× 普通に考えて
〇 俺の頭の中で

× 妥当な理由はない
〇 妥当な理由は思い当たらない

テンプレートなら初期化は不要という主張なら、
constexpr 変数の宣言と定義を分離できないことは納得してるのかな?
そうだとして、それをテンプレートの時だけ可能とすることに意義があると思うの?

特別ルールを設ければコンパイラ実装やプログラムの読み取りにコストがかかるから、
明確が意義がなければ特別ルールは無いのが妥当だと思うよ。
0884デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:24:42.79ID:QUVSvjZy
>>880, >>883
マウント取るのが最優先でまともな回答できない(するつもりも無い)んなら黙っててくれ

>これは宣言と定義じゃなく定義の重複だぞ
externつけたら?

>それをテンプレートの時だけ可能とすることに意義があると思うの?
テンプレート実引数に使われる型が不完全型であっても、実体化まで評価を遅らせられる

さて、
>× 普通に考えて
>〇 俺の頭の中で

>× 妥当な理由はない
>〇 妥当な理由は思い当たらない
こんなゴミみたいな煽り入れてきたからには逃げるなよ
0885デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:32:39.86ID:SZLGcxYz
>>884
おまえさんの元の質問はこうだったな
template <typename T> constexpr inline T value;
template <typename T> constexpr inline T value = (T)0;

どこにexternなんて書いてある?
マウントがどうたら気にするあまり後出しなんかしてるのはそっちだぞ
こっちはそんなこと微塵も考えちゃいねえよ失敬な
最初の口調に戻れよ
0886デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:36:57.55ID:QUVSvjZy
間違えた
Xテンプレート実引数に使われる型が不完全型であっても、実体化まで評価を遅らせられる
○初期化に使われる定数式の評価を遅らせられる

言い換えれば、宣言と定義を分離できないならconstな変数テンプレートの宣言時には
それに使う定数式内のすべての型が完全型であることを強制されてしまう
=std::is_integral_v = std::is_integral<T>::valueでいえば
is_integral構造体の方が取り回しがいい、ということ
なんのために変数テンプレートが導入されたのか・・・・
0887デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:37:56.58ID:QUVSvjZy
>>885
自分が失敬だからこうなってるとは考えられないんだな
何様だよ、そもそも質問に答えてないだろうが
0888デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:43:43.09ID:SZLGcxYz
>>887
template <typename T> constexpr inline T value;
template <typename T> constexpr inline T value = (T)0;
を例示しての質問に対して
int test;
int test = 5;
という答えをしているぞ
valueがtestになったのは悪かったが
余計な飾りをとって問題の核心を指摘したんだよ
0890デフォルトの名無しさん
垢版 |
2019/12/14(土) 15:58:10.05ID:QUVSvjZy
規格でそうなってる(テンプレートゆえの特例は無い)のが”わかってるなら”
最初からそう言ってくれれば済むんじゃないの?
>>854を読み直せよ、テンプレートのことが完全にすっぽぬけた上に失礼な回答だろ

>コンパイラのバグとまで言う根拠は何だ?
とまで、って・・・・普通にありえるだろ、動作が違うんだから(未定義とかいう屁理屈は無しで)

で、>>883は逃げたの?
0891デフォルトの名無しさん
垢版 |
2019/12/14(土) 16:55:24.17ID:k5kIl1RN
>>886
やっぱり constexpr 変数の宣言と定義を分離して何がしたいのか、
何ができるようになるのか、が見えてこない。ごめんね。

宣言だけ見える constexpr 変数への参照やポインタだけはとれるようになるけど、
それだともう constexpr である必要なくて const 変数でよさそうで、それならふつうに
宣言と定義は分けられるし。

ちなみにテンプレート実体化までテンプレート引数依存箇所の評価はされないから、
宣言と定義を分ける話を「評価を遅らせられる」と言い表しているのも何か間違ってそう。
「記述を遅らせられる」の間違い?
0892デフォルトの名無しさん
垢版 |
2019/12/14(土) 17:16:54.80ID:SZLGcxYz
だめだこいつ
絶望的に人に者を尋ねる態度がわかってない
「言ってくれれば済む」とか図々しすぎ
技術的な議論がしたいがこいつ相手では
不必要にイラついちまって無理だわ
俺そんなに人間できてない
0893デフォルトの名無しさん
垢版 |
2019/12/14(土) 17:24:00.92ID:QUVSvjZy
>>891
すまん、
>テンプレート実体化までテンプレート引数依存箇所の評価はされない
これ検証してみたらたしかにそうだった
手元のコードで完全型を要求されたから、初期化時に不完全型を使えないと思い込んでた
(おそらくconstexprな変数テンプレートの実体化が、必要な型の実体化より先に来てたっぽい
多分構造体か何かでワンクッション置けば解決できると思う)
これなら確かに分けられなくて問題無いね

>>892
>いいか、constexprは翻訳時定数だぞ
>それを翻訳段階9まで未解決のままにできると思うか?
>なんかとんがってんな
>後出しなんかしてるのはそっちだ
>余計な飾りをとって問題の核心を指摘したんだよ
さらには
>最初の口調に戻れよ
の上で
>技術的な議論がしたいがこいつ相手では
>不必要にイラついちまって無理だわ
よくそんなセリフが言えたもんだ
自己評価高すぎじゃない?wwww
0894デフォルトの名無しさん
垢版 |
2019/12/14(土) 17:52:18.36ID:SZLGcxYz
意見が合うとか合わないとか以前の問題
根底的なメンタリティに欠陥がある相手とは話にならない
0900デフォルトの名無しさん
垢版 |
2019/12/14(土) 21:15:53.72ID:SZLGcxYz
禿もそんなことを言いながら
virtualの導入には当初反対から出発したんだよな
0902デフォルトの名無しさん
垢版 |
2019/12/15(日) 09:10:03.56ID:LATD77rz
君が忘れた腕時計見つめながら。
0904デフォルトの名無しさん
垢版 |
2019/12/15(日) 10:52:20.53ID:LATD77rz
ツリーのイテレータがあるとして、イテレータが返すのはノードじゃなくて、ノードの持つ値ですよね?
すると、イテレータは立体機動出来ないといけなくなるけど、begin().begin()とか変ですよね?
begin().parent()とか。
0905デフォルトの名無しさん
垢版 |
2019/12/15(日) 10:59:28.89ID:LATD77rz
イテレータが返すじゃなくて、イテレータの逆参照が返すかな。
0906デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:08:51.65ID:fGq+HT2S
コレクションとしては子孫ノード全部を列挙できればよくて、ツリー構造に沿った操作が行いたいなら
それに加えて直接の子ノードのみを列挙するイテレータが用意できればいいだろう。
0907デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:17:54.16ID:LATD77rz
何が子ノードのみを列挙するイテレータを返すかがよくわからない。
ノードの値がイテレータを返すことはできないので、ノードが子ノードを指すイテレータを返すとすると、イテレータの逆参照はノードを返すことになる。
これは意味論的にちょっと違うかなって。
コレクションにおいて位置はイテレータで示されるので、立体的な位置を持つツリーでは、イテレータ自身が立体機動出来て、巡回能力を持つイテレータは、reverse_iteratorのように外部に用意されれば良いのかなと思ったんだけど。
たとえば、レベルオーダーや深さ優先の巡回イテレータがあるとすると、普通に考えるとスタックやキューが内部に必要にある。
というわけでコピーのコストがあるので、これを標準には出来ないんじゃないかなって。
0908デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:22:50.93ID:LATD77rz
子ノードを指すイテレータの逆参照が子ノードを返すとすると、*node.begin()は子ノードを返す。
**node.begin()は最初の子ノードの値を返すことになるんだけども。
イテレータの逆参照がノードを返す場合、初期化子リストが素直に実装出来てイイんだけども、イテレータの逆参照が値を返さないのが腑に落ちない感じ。
0910デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:27:25.99ID:LATD77rz
イテレータは演算子の実装を求められてるわけではなく、その演算子を呼び出した時の効果を求められてるだけなので、++(int)はスタックをコピーしない方法を考えた。
0911デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:30:57.88ID:fGq+HT2S
そこは値じゃなくてノードを返すイテレータでいいんじゃね?
必要ならイテレータ自体を拡張してもいいだろうけど、この場合はあまり応用できそうもないし。
0912デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:31:53.05ID:LATD77rz
そうなのかな?
0913デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:37:55.15ID:PfQY9kAx
まずイテレータで何を抽象化したいかを明確にしなよ
ノードを意識させたいのか?
0914デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:38:38.78ID:LATD77rz
STL風ツリーって検索しても絶対出てこないし、CIAが絡んでるような気がしてきた。
0915デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:39:36.48ID:LATD77rz
そこがわかんないんだよねえ。
禿4とか読んでると、イテレータは位置を意味してるように思うんだけど。
0916デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:45:00.74ID:mSzJWPy5
ツリー構造
範囲が広すぎて
汎用化すると使い勝手が悪くなるからしない
ってだけかと
0919デフォルトの名無しさん
垢版 |
2019/12/15(日) 12:22:05.91ID:Q+saMC6e
いや立体がどうたら言ってるから
じゃあrecursive_directory_iteratorを使うユーザーのコードは
いちいち多重ループだの再帰だのといった処理になるのかって
思ってさ
0920デフォルトの名無しさん
垢版 |
2019/12/15(日) 12:24:23.41ID:LATD77rz
ツリーは、あるノードの親が知りたいときもあるはず。
0921デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:07:24.45ID:TeOOTcIs
ごちゃごちゃ考える前にイテレータの本分を決めなよ
begin()からend()まで++で走らせた時にどうなってほしいの?
話はそれからだ
0922デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:09:44.18ID:MBW+LfoG
一般にtreeの探索順序はアルゴリズムと深く結びついてるし、
そこ凝りだすと沼だぞ。
0923デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:09:51.26ID:5G1zfwod
関数ポインタをシリアライズしてファイルとして保存し、
ファイルからその関数ポインタを利用できる形に復元する方法ってあるのでしょうか?
0926デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:20:48.30ID:hicN34V0
次に(別のプロセスで)ファイルを読み込んだときに、
元の関数を同じ番地で参照できると限らんしな。
関数ポインタの配列のインデクスなら大丈夫だろうだけど。
0928デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:39:23.84ID:2FA7t6Jx
C++20以降のvector/stringとか
使われる時にconstexprであることを妨げないようにするために付いてるんだと思う
0929デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:47:38.10ID:LATD77rz
どうもありがとう。
0931デフォルトの名無しさん
垢版 |
2019/12/15(日) 14:30:37.97ID:o9m7qUoD
デストラクタがデフォルトでvirtualじゃないのは設計不良ではあるまいか
0934デフォルトの名無しさん
垢版 |
2019/12/15(日) 15:15:03.49ID:K1ul1r/C
>>931
C++では基本的にゼロコストでできるところはそうできるようにするポリシーだからvirtualが必要なときだけvirtualを明示的に指定させる、というのをどこかで読んだ気がする
0936デフォルトの名無しさん
垢版 |
2019/12/15(日) 16:19:56.16ID:AolOnHel
そうするとメタプログラミングに色々と支障が出たはずだし
STLも結構継承使ってるから実現出来なかったかコスト増えてるよ
0937デフォルトの名無しさん
垢版 |
2019/12/15(日) 16:52:10.11ID:TkLVy9px
デストラクタをvirtualにする必要があるのは、baseのポインタ経由でdeleteする場合だけ
baseのポインタを使うことすらないようなもの(CRTPなど)までvirtualになるのは
どうなんだろうか
0939デフォルトの名無しさん
垢版 |
2019/12/15(日) 17:16:05.58ID:p2D9PeH2
>>938 んなこたーない。
shared_ptr<Base>{new Derived} なら virtual デストラクタ不要になるから、間違えて覚えてるだけでは?
0941デフォルトの名無しさん
垢版 |
2019/12/15(日) 19:10:50.35ID:AolOnHel
セオリーとして覚えてる人多いけど、何故なのかまで考えてない人が多い例の一つだね
要するにdeleteする基底のポインタからデストラクタを呼ぶ際に末端のデストラクタを呼ぶ方法(vtable)が必要というだけ
末端のデストラクタを呼べれば、そこから基底のデストラクタを呼んでいくのは何が基底かわかりきってるから自動で出来る
0942デフォルトの名無しさん
垢版 |
2019/12/15(日) 19:29:34.24ID:tmrMX5L5
>>941
>基底のポインタからデストラクタを呼ぶ際に末端のデストラクタを呼ぶ方法(vtable)が必要というだけ
mjk、
0943◆QZaw55cn4c
垢版 |
2019/12/15(日) 19:42:55.10ID:gCPcwtH+
永遠の初心者です、お願いします
1. 式で if 文を表現したいときは条件演算子(三項演算子 ?: )が使えますが、同じく式でループ構造を表す方法は C++11 以後にありますでしょうか?
2. 1 の質問の理由としては、C++ は Java とちがって uper() がなく、派生クラスのコンストラクタの基底クラス初期化部分に式しか書けません、ここにループを書くとすれば「コンストラクタ用メンバ関数(メソッド)」を置いていますがいかにも無様だと思っています…
3. ある既存のクラスに皮をかぶせて機能アップを図るとき、もとのクラスの派生クラスとして機能アップ部分を既述することは、よくある定石でしょうか、それともあまりしないことでしょうか?

---
以上3点の質問は以下のプログラムを書いていて感じました
お題は「エラトステネスのふるい」、ただし、当初、まっとうにふるいを書いた後、機能アップ項目として
篩部分に格納する数は 2n + 1 奇数に限定する、あるいは 6n + 1, 6n + 5 の形のみに限定する
等を元の篩に対して派生クラスとして記述しました
https://ideone.com/YPlfsC
0945デフォルトの名無しさん
垢版 |
2019/12/15(日) 20:05:17.27ID:5sPbacoo
エラストテネス
6n+1, 6n+5だけ保持とかってみんな考えるよね

ちなみに
巨大なテーブル作成時のパフォーマンスを上げるなら
キャッシュが効くよう分割処理するのが非常に効果的
スレッド分割の為にいずれにしろ分割処理は作る事になる
0947デフォルトの名無しさん
垢版 |
2019/12/15(日) 20:14:20.76ID:mkXjftMX
高分子エラストマー
0948はちみつ餃子 ◆8X2XSCHEME
垢版 |
2019/12/15(日) 20:20:59.00ID:jthcUe0A
>>943
初期化部分に複雑な処理をベタ書きする方が無様だと思うよ。
初期化リストの中にそんなごちゃごちゃしたこと書きたい?
ワイが思うだけなので世間でどう思われてるかは知らんけどとりあえずひとつの意見として。
0949デフォルトの名無しさん
垢版 |
2019/12/15(日) 20:54:13.00ID:TKBas8kS
>>939

親クラス(Base)のデストラクタに virtual 付けなくても...
{
shared_ptr<Base> obj( new Derived() );
} // ~Derived() called, then ~Base() called.

~Derived() はコールされるんですね... 確認してみて驚きました。
これができる仕組みを誰か教えてください。
スマートポインタのオブジェクトは子クラスの事何も知らないのに
どうして ~Derived() のコールが可能なのでしょうか?
0952デフォルトの名無しさん
垢版 |
2019/12/15(日) 21:24:07.01ID:tmrMX5L5
質問ですが構造体Fooの内側に構造体Barが定義されているという入れ子になった構造体において、
Fooの外のコードでFoo::Barのサイズをsizeof()で知りたいとき、以下は正しい?
1. C++だとsizeof(Foo::Bar)と書いたらおk
2. CまたはC++でもC互換構文の範疇で済ます場合、次のどちらかの方法でしか書けない
(1) Foo::Barのインスタンスyが存在するスコープ内で、sizeof(y)と書く
(2) Fooのインスタンスxが存在するスコープ内において、Foo::Bar型のメンバyをFooが持つ
    (Foo::yが定義されている)という条件の下で、sizeof(x.y)と書く
0953デフォルトの名無しさん
垢版 |
2019/12/15(日) 21:39:08.56ID:tmrMX5L5
ふとオモタがインスタンスの必要性は無くせるかもしれん
Foo::Bar型のメンバFoo::yが定義さえされておれば、Fooのインスタンスが無くても
 sizeof(((Foo*)0)->y)
と書けばC言語で逝けるかもしれん…
スゲー気持ち悪いコードだが、、、、
0954デフォルトの名無しさん
垢版 |
2019/12/15(日) 21:46:34.52ID:PfQY9kAx
>>951
あくまでコンパイル時の型で決まるだけだから要注意
例えば

class A;
class B : public A;

A* p = new B();
std::shared_ptr<A> a(p);

これだとBのデストラクタは呼ばれない
レス数が950を超えています。1000を超えると書き込みができなくなります。

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