C++相談室 part153

レス数が950を超えています。1000を超えると書き込みができなくなります。
2020/10/10(土) 23:18:20.00ID:i4F+i14Y
https://mevius.5ch.net/test/read.cgi/tech/1589424805/
※前スレ
C++相談室 part152
https://mevius.5ch.net/test/read.cgi/tech/1594528940/

テンプレおしまい
2020/12/23(水) 19:39:04.22ID:PgZc4XsV
前者
2020/12/23(水) 19:43:53.01ID:PgZc4XsV
多くのコンパイラは以下に変形しそうな気がする
if (X-100u<900u)

後者をコンパイラが最適化するかどうかはコンパイラ次第
2020/12/23(水) 19:47:49.74ID:PgZc4XsV
PCなら1秒に1万回程度なら気にしなくて良い
8bitマイコンだとこの判定だけでも10個以上の命令になったり
855デフォルトの名無しさん
垢版 |
2020/12/23(水) 20:03:20.62ID:rWjdGSAm
長さ数十億のbool型配列用意すれば早いんじゃね
isDigit3[x] だけで出るじゃん
2020/12/23(水) 20:04:42.24ID:psZzhFw3
>>851
それ条件式が間違ってるだろ
2020/12/23(水) 21:04:06.12ID:oO0RWe4j
根本的には、速度って環境依存の性質だから、本当に重要な話なら実測で確かめるしかない。

一般論としては、現代のコンパイラはそこらの人間より賢いから、やりたいことを素直に書いて最適化を任せるのがいい。
わかってない人が余計なことをやると、かえって遅くなる可能性が高い。

計算量のオーダーを変えるような、アルゴリズムレベルの最適化なら意味があるんだけど。
小手先のテクニックは通用しないと思っていい。
2020/12/23(水) 22:00:42.78ID:p3n5tJou
>>850
いうてほんとに定数式になってくれないと困る場面で定数評価してくれない事態に出くわしてないんだよなぁ・・
constexprなクラスとか作ってればあるのかもしれんが
2020/12/23(水) 22:21:55.80ID:JqE6cd4a
最適化にも限界はあるから、どういうコードの書き方ならコンパイラが最適化しやすいか、
ってのを知るのは必要なんやろうね
データアクセスの局所化とか偽の依存関係の除去とか
860デフォルトの名無しさん
垢版 |
2020/12/23(水) 23:11:04.90ID:pgaSoeQc
typedefで二重定義になった場合さぁ…同じ型だとコンパイルエラーにはならないんだよ…
なんか気持ち悪いので…typedefだけのヘッダーを呼ぶようにしたけど…同じ型だとOKなん?
861デフォルトの名無しさん
垢版 |
2020/12/23(水) 23:12:13.58ID:pgaSoeQc
ヘッダーに渡しても同じことか…相互参照してるんだった…
862デフォルトの名無しさん
垢版 |
2020/12/23(水) 23:13:21.42ID:pgaSoeQc
一応…間違えないように…ヘッダーに集約しておく…
2020/12/23(水) 23:13:34.29ID:KqYWGLnc
Ruby VM では、1秒間に、100万回ループすると、
Ruby中間言語を、JIT で機械語にコンパイルして、

1秒間に、1,000万回ループ出来るようになる
2020/12/23(水) 23:43:55.33ID:iOQdV6uo
いや指定した数だけループしろよ
何勝手に回数10倍に増やしとんじゃい
865デフォルトの名無しさん
垢版 |
2020/12/24(木) 06:19:28.22ID:TzdYJrci
サムソンを守るためのHuawei潰しという側面もある。
2020/12/24(木) 06:55:00.49ID:fOK7nTKz
んあ?
867デフォルトの名無しさん
垢版 |
2020/12/24(木) 06:58:51.74ID:TzdYJrci
文大統領がトランプ大統領に、Huaweiを潰すよう勧めたそうです。
2020/12/24(木) 07:53:25.30ID:X8ie3AzF
>>863
C++ならはじめから秒2000万回ループできるコードになる
869デフォルトの名無しさん
垢版 |
2020/12/24(木) 08:12:44.86ID:TzdYJrci
このプログラムは応答していないためシステムによって閉じられますって出るんじゃないの。
2020/12/24(木) 10:18:24.14ID:ys2W6z1g
>>860
OK
https://timsong-cpp.github.io/cppwp/n3337/dcl.typedef#3
2020/12/24(木) 11:16:41.02ID:h4Gph9I0
>>854
手元の32bitマイコン(除算器なし)だと
uint16_t v; に値入ってたとして、
if(v >= 100 && v < 1000) よりは ((v >= 100) & (v < 100p
2020/12/24(木) 11:27:11.76ID:h4Gph9I0
>>871
途中で送ってもうたorz

((v >= 100) && (v < 1000))のが気休め速い感じだったな。
あとLUTもほぼ変わらん。LUTはもう少し複雑な計算で、
かつキャッシュにテーブルが入ってくると鬼速だろうけど。

単純な比較のみだからあまり速い方法ないのかもね〜
ダメ元で掛け算とビットシフトで/100する処理も試したけど
ちょっと遅くなったorz

つか、32bitマイコンだと100us周期程度の割り込みハンドラで
この水準まで自分は気にしないだす。
あとC++ならinline化とかその辺をまずチェックでしょうさ。
2020/12/24(木) 17:12:04.54ID:tg7gMCA8
>>872
if ((unsigned)v - 100u < 900u)
のが早くない?

テーブルは論外だ
アドレス計算コストの方が高そうだし
ROMサイズやキャッシュ汚染などの悪影響がある
2020/12/24(木) 19:53:19.25ID:9+0irhfK
if ((unsigned)v - 100u < 900u)
こういうのは減算とコンペア(実質減算)の2回の演算が常に走るから必ずしも速くないんじゃないかな。
&&で繋ぐ方がショートサーキットが働いて1回で済む場合がある。
演算で0との比較に落とせるなら別だけど。
2020/12/24(木) 19:56:18.95ID:VQIKvM0h
そのくらいなら最適化に任せた方がいい気がするが……
2020/12/24(木) 21:38:01.43ID:B83YCBUh
比較がボトルネックってのは本当だろうかとは思わなくもない
まあ、データ転送とか切り詰めまくって残すは比較のみ、ってのもありうるけど
2020/12/24(木) 21:38:20.67ID:X8ie3AzF
整数の減算は非常に高速
条件分岐は遅いし分岐予測を汚染する

コンパイラの最適化を見てると良い
範囲判定は大抵>>873のようなコードになる
2020/12/24(木) 21:41:03.65ID:X8ie3AzF
コード的には普通に
if (100 <= x && x < 1000)
と書いておけば良い

コンパイラが最適化するから

x/100を比較するのは
意味的にも意味不明だし
速くなることもない
2020/12/24(木) 21:51:18.77ID:X8ie3AzF
ISRの最適化なら

レジスタを節約して待避する数を減らすとか
レジスタバンクを使ってレジスタを切り替えるとか
RAM上で実行するとか
割り込みを許可せずに高速化とか(MIPSの場合)
まあ色々とチューニング出来る余地がある

小規模DSPなんかだと
いまだにISRをアセンブラで書いたりする
880デフォルトの名無しさん
垢版 |
2020/12/25(金) 14:04:51.84ID:L6KY61Ck
バンク切り替えテクニックですか。
むかしのインターフェース誌っぽいですね。
2020/12/25(金) 17:40:14.36ID:j6GWo/XP
昔のテクニックが今でも有効
2020/12/25(金) 20:23:57.32ID:KGl9PDWX
template<size_t A, size_t B>
class tmp{};

template<size_t N>
void test(tmp<N, N>&){
std::cout << “A”;
}

template<size_t A, size_t B>
void test(tmp<A, B>&){
std::cout << “B”;
}

上のような関数があったときにtest(tmp<1,1>{});がどちらを呼ぶか規格で決まってる?
2020/12/25(金) 22:18:37.12ID:9Tm+xBHp
テンプレート引数が少ないtmp<N, N>の勝ち
884デフォルトの名無しさん
垢版 |
2020/12/26(土) 00:14:55.00ID:biNpl0R5
using FunctorType = std::function<void()>;
struct RecursiveMapperType;
using InternalMapperType = std::map<std::string, RecursiveMapperType>;
struct RecursiveMapperType : public InternalMapperType
{
RecursiveMapperType(){}
};

こういうコードをネットで見かけたんだけど
RecursiveMapperTypeを前方宣言してInternalMapperTypeを宣言
RecursiveMapperTypeをInternalMapperTypeを継承して作成していることのメリットがよくわからない。

struct RecursiveMapperType : public InternalMapperType
{
RecursiveMapperType(){}
};
using RecursiveMap = std::map<std::string, RecursiveMapperType>

だとだめなのだろうか?
誰か教えて下しあ
2020/12/26(土) 00:40:10.65ID:3VlCU3bq
>>884
上のコードと下のコードの RecursiveMapperType の定義はまったく同じに見えるんだけど、何が違うの?
886デフォルトの名無しさん
垢版 |
2020/12/26(土) 00:50:04.37ID:biNpl0R5
>>885 さん
すみません。
下の方のRecursiveMapperTypeですが継承元消し忘れてました。
下のようなkたちです
struct RecursiveMapperType
{
RecursiveMapperType(){}
};
using RecursiveMap = std::map<std::string, RecursiveMapperType>
2020/12/26(土) 03:46:58.69ID:fBIAR6pR
ttps://ideone.com/Ou2BZq
2020/12/26(土) 15:10:58.71ID:3VlCU3bq
>>886
それじゃ全然機能が違うっていうかその RecursiveMap 何の役にも立たないでしょ。
元の RecursiveMapperType の機能が理解できてないだけか。
2020/12/26(土) 16:40:20.18ID:vGzfsLf/
再帰的な構造を定義したくて自分自身の型を含めたものを継承してるわけで
それを実現するには前方宣言するしかない
というね
890デフォルトの名無しさん
垢版 |
2020/12/26(土) 17:13:57.40ID:UNoc468U
再帰的なコンテナは、フィールドが出来た時点で破綻するのでは?
891デフォルトの名無しさん
垢版 |
2020/12/26(土) 18:07:48.30ID:TLGOuMOF
https://cpprefjp.github.io/reference/vector/vector.html
>不完全型を要素にする例 (C++17)

これの亜種
892デフォルトの名無しさん
垢版 |
2020/12/27(日) 06:31:05.42ID:QkMmRpj8
C++23に持ち越された契約は何が変わるんだろね。
893デフォルトの名無しさん
垢版 |
2020/12/27(日) 17:59:23.18ID:wQ5c+q6H
ありがとうございます。なんとなくイメージできました。

コードの設計ってまだよくわからないのですが、
再帰処理のためにこうするのって比較的普通なことなんですか?
2020/12/27(日) 18:23:25.49ID:tp3tetyk
>>893
知らんよ。
普通かどうかなんて気にしてどうするの?ここで名無しの誰かに yes/no 答えてもらって何か意味ある?
2020/12/27(日) 18:33:52.26ID:7Rx7y5wp
>>893
STLのクラスを継承して階層構造を実現するテクは応用編って感じがする
もっと基本的なやり方をするならデザパタのcompositeパターンを使う
とかかね
2020/12/27(日) 18:47:54.32ID:7Rx7y5wp
設計を学ぶならデザパタはひと通り見ておいて損はないぞ
897デフォルトの名無しさん
垢版 |
2020/12/27(日) 18:49:43.74ID:QkMmRpj8
ヘネパタ、パタヘネ、デザパタ。
898デフォルトの名無しさん
垢版 |
2020/12/27(日) 22:11:00.35ID:QkMmRpj8
newのコストは気にされますが、deleteのコストは見逃されがちです。
2020/12/28(月) 02:23:23.12ID:ibU6N4ur
あるクラスのコンストラクタのデフォルト引数を変更するときってどうしたらいいの?
オーバーロードすれば良い?
2020/12/28(月) 07:27:12.64ID:7Z4wU2qk
単純に変更じゃダメな理由は?
他のライブラリ?
2020/12/28(月) 07:33:40.98ID:pesKZps1
stlコンテナを継承するのはアウトだろ。
うまくやらないとデストラクタが呼ばれなくなっちゃうぞ
902デフォルトの名無しさん
垢版 |
2020/12/28(月) 09:00:44.26ID:i4NtF28F
じゃあうまくやりましょうや。
2020/12/28(月) 09:44:51.94ID:bVWPeYFg
そもそもC++ではデストラクタを仮想にしてないってことは「継承すんなよ」って宣言だからなぁ
904デフォルトの名無しさん
垢版 |
2020/12/28(月) 09:55:45.06ID:W/k+iOkV
なんで継承しないようにしたか意見表明文みたいなモンはどっかにあるのか?
2020/12/28(月) 10:20:49.88ID:ErVwTltE
仮想関数化するとしない場合に比べて余分なコストがかかるから、必要な理由がない限り基本的にそれは避けるということじゃないかな
2020/12/28(月) 10:32:20.80ID:4OiRlqvR
C++は1クロックでも速く動作させるために非仮想関数をデフォルトにしたのは理解できる
Javaは動作速度よりもオブジェクト指向の継承動作の一貫性を重視してすべて仮想関数にした、これも時代を考えれば理解できる
C#もJavaと同じくデフォルトを仮想関数にしておいて欲しかったのだが、C#はC++を尊重してデフォルト非仮想関数なんだよね
これはちょっと残念
2020/12/28(月) 11:33:10.90ID:s2RdB6EU
継承して機能追加っていうのがオブジェクト指向的にもどうかと思うね
2020/12/28(月) 12:34:23.27ID:QmdcnH/3
finalキーワードがこの時代にあれば間違いなく付けただろうな
文句言ってる奴はガイジ
2020/12/28(月) 12:42:44.62ID:UEnoPUHl
>>903
継承すんな、は言いすぎ。
private継承なら問題ないと思うけど。実際たまに使われているし。
2020/12/28(月) 13:19:25.85ID:N6A7dpOQ
デストラクタが仮想ではないものを継承したときの具体的な問題は
スライシングが起こりうるということと、
起こってもコンパイラが (少なくともコンパイル時には) 捕捉できないことが多いということにあって、
スライシングが起こらないように使う分には問題はない。

設計的に綺麗かどうかはまた別の話だけど。

shared_ptr が (デストラクタが仮想でなくても) 元の型のデストラクタを呼んでくれたりするんで、
場合によってはそういう設計もアリということなんだと思う。
2020/12/28(月) 14:12:57.70ID:02+J4aSB
>>910
デストラクタが仮想なものを継承してもスライシングは起こりうるよね?そこは関係なくね?
https://en.wikipedia.org/wiki/Object_slicing
> In C++ programming, object slicing occurs when an object of a subclass type
> is copied to an object of superclass type: the superclass copy will not have
> any of the member variables defined in the subclass. ...
2020/12/28(月) 17:31:09.93ID:V+A6vVBD
C++自由すぎてしんどいな
後方互換性と引き換えに払った代償か
2020/12/28(月) 17:46:19.93ID:N6A7dpOQ
>>911
スライシング自体は起こるけど、それで予想外のことやメモリ管理の矛盾は起こり難い。
914デフォルトの名無しさん
垢版 |
2020/12/28(月) 17:50:37.04ID:i4NtF28F
自由に羽ばたける翼。
2020/12/28(月) 18:06:08.49ID:V+A6vVBD
自由すぎて困る部分はLinterを併用することで勝手に回避しろってことかな
2020/12/28(月) 18:37:15.29ID:v+s+VlFU
だってCの設計思想が「人間を信用する」だもん
セキュリティが重視される現代的な言語のベースとしては致命的に合ってないんだよね
2020/12/28(月) 18:40:02.12ID:02+J4aSB
>>913
やっぱり関係がわからない。
デストラクタが仮想ではないものを継承したときに限ってスライシングが予想外のことや
メモリ管理の矛盾につがなる例をひとつでいいから見えてもらえない?
2020/12/28(月) 18:40:41.01ID:02+J4aSB
s/見えてもらえない?/見せてもらえない?/
2020/12/28(月) 19:07:39.46ID:bVWPeYFg
A <|- B, C みたいなときにB, CをnewしてA*として管理しようとすると破棄の時にAのデストラクタしか呼ばれない
2020/12/28(月) 19:09:58.26ID:UEnoPUHl
>>911
仮想でないデストラクタが話題のスコープなのに、スライシングにスコープを移したら議論にならないでしょ。

911) デストラクタが仮想なものを継承する→スライシングになるものが存在する
という命題は
910) デストラクタが仮想ではないものを継承する→スライシングになるものが存在する
という命題と矛盾するわけではない(両立する)ので、その議論はあんまり意味がない。
921デフォルトの名無しさん
垢版 |
2020/12/28(月) 19:14:08.97ID:i4NtF28F
スライシング・オプティマイザーとかどうよ?
2020/12/28(月) 19:36:49.42ID:02+J4aSB
>>910
> スライシングが起こらないように使う分には問題はない。
ここもおかしいんだよね。

デストラクタが仮想ではないものを継承して派生クラスのオブジェクトを new で作って
基底クラスのポインタを通して delete したら未定義動作になるわけだけど、
これはスライシングを起こしていなくても問題になる。

「派生クラスのオブジェクトを new で作って基底クラスのポインタを通して delete」のことを
「スライシング」と呼んでる気配もあるんだけど、それは明らかに誤りだろうし。
2020/12/28(月) 19:43:43.44ID:592FfNkQ
>>900
変更ってどうやるの?
毎回好きな引数を与えよってこと?
面倒なので、自分の好きな引数を自分のコードの中ではデフォルトにできれば良いのにと思ったのだが、こういう考えは間違っていますか
2020/12/28(月) 19:51:33.62ID:7Z4wU2qk
>>923
make関数作るのはダメなん?
2020/12/28(月) 19:59:11.40ID:v+s+VlFU
デストラクタはpublic仮想かprotected非仮想かpublic非仮想finalのどれかにしろ
っていう一般的結論でよくね
2020/12/28(月) 21:21:17.65ID:sYj4+JXZ
>>925
自分で書くときはそう
標準のコンテナのように既存のクラスがそうでなかったら?が発端だからなぁ

個人的には仮想デストラクタがなければ継承はしない
(一部のイディオムを除けば)private継承にするくらいなら委譲する。
2020/12/28(月) 21:54:56.73ID:wzipnhb8
デストラクタがprotected:であっても非仮想なら継承したらアウトなんじゃ…
派生クラスの破棄時に基底クラスのデストラクタが呼ばれない
的な意味で
2020/12/28(月) 21:57:44.66ID:dWPs/bUX
>>924
オブジェクトを作るための関数を作ってはどうかという意味ですか?
確かにそれで良いのでそうします
929デフォルトの名無しさん
垢版 |
2020/12/29(火) 07:11:18.52ID:2gsaGKLd
相称型プログラミング。
930デフォルトの名無しさん
垢版 |
2020/12/29(火) 07:28:15.94ID:2gsaGKLd
いま私大事なこと言いましたよ。
2020/12/29(火) 07:37:07.18ID:H8QGk97F
プログラミング学びには来ないだろ
こんな途上国に
932デフォルトの名無しさん
垢版 |
2020/12/29(火) 07:38:50.44ID:2gsaGKLd
【CSS規格、読書感想文】
CSSがアイデアであった段階からスクリプト言語で実装され、初の大規模採用であったネットスケープにおいてもJavascriptによって実装されていたため、規格そのものがC/C++で効率的になるよう設計されていない。※
現行の規格に対して効率的な実装を施したとしても、将来の規格バージョンで維持できると限らないため、結局、スクリプト言語と同様の非効率を許容することになる。
これはつまり、ほとんどのシンボルを動的に確保することを意味する。

※HTML5規格は、C/C++で効率的に実装できるように仕組まれている。
2020/12/29(火) 07:48:03.75ID:UwKcs/oz
なるほどねー
そもそもCSSのCって要る?
もはやスタイルシートってサイト作成者が決めるものになっているよね
ユーザースタイルシートをカスケード適用できる機能もなくせばさらに効率よくできそう
2020/12/29(火) 07:49:27.20ID:oaU8v0Mt
>>927
なんで?~Derived()が~Base()を呼ばない場合なんて存在しないぞvirtualの有無関係なく
2020/12/29(火) 08:05:44.29ID:vWMLZNcx
>>927
型消去とsmart ptr実装で調べるよろし。
2020/12/29(火) 09:18:16.16ID:qLyTNuLW
定期的に話題になるけど、基底のデストラクタにvirtualが必要なのは
基底型のポインタでdeleteするときだけな
末端のデストラクタさえ呼べれば、次に呼ぶ基底の型は分かりきってるからね

別の言い方をすれば、常に末端の型のポインタをdeleteする分には、virtualなデストラクタなんか要らんということ
2020/12/29(火) 11:55:36.33ID:So4DneUg
ポリモーフィズムの旨味が消えるw
938デフォルトの名無しさん
垢版 |
2020/12/29(火) 12:13:46.12ID:2gsaGKLd
ポリリズムから出汁をとったみたいないい方しますね。
2020/12/29(火) 13:15:00.89ID:m86wB2y9
まあ普通は末端の型を意識しなくて済むからこそ派生の旨味がある訳で
2020/12/29(火) 14:33:08.60ID:kdP0thHS
>>936
その点については誰もが一度は通る勘違いだよなw
最初はわけも分からず機械的にvirtualつけて回ってたわ
2020/12/29(火) 20:19:15.83ID:EiaQ+UBu
うっせえ知っとったわ素でまちがえただけじゃわ!ヽ(`Д´)ノウワーン
2020/12/31(木) 05:29:21.52ID:/Sdg/sCQ
struct A { virtual void Delete() { delete this; } };
struct B : A { void Delete() { delete this; } };
こうなってりゃ別にいらんな
943デフォルトの名無しさん
垢版 |
2020/12/31(木) 11:50:06.55ID:zS3i4lwe
>>795 の同期とか奇妙な質問に思うけど、Javaからくるとそうなるんだな。
2020/12/31(木) 12:23:37.15ID:3Es5+lkr
javaにだって非同期でメモリ確保するコンテナなんてないでしょ
2020/12/31(木) 13:41:11.66ID:lvvsunYH
>>942
おとなしく virtual ~A() とするのにくらべて何のメリットも無いな。
946デフォルトの名無しさん
垢版 |
2020/12/31(木) 13:43:11.73ID:zS3i4lwe
deleteのコストは、ほんと気にされないな。
2020/12/31(木) 15:24:44.84ID:eCxLbtN/
「a=1 かつ b=1 以外なら実行」って条件式はどう書くの?
2020/12/31(木) 15:31:08.20ID:7G3T5w7B
>>947
母語で曖昧さの無い表記ができますか?
2020/12/31(木) 15:40:19.22ID:+0BPso5e
>>950

> 「a=1 かつ b=1 以外なら実行」って条件式はどう書くの?

「「a=1 かつ b=1」以外なら実行」なら、
if (!(a == 1 && b == 1)) { 実行(); }

「a=1 かつ「b=1以外」なら実行」なら、
if (a == 1 && b != 1) { 実行(); }
2020/12/31(木) 15:47:49.87ID:eCxLbtN/
>>949
THX
「a=1 かつ b=1」以外なら実行、でした。
私が950でレスするのもお見通しですか?w
2020/12/31(木) 18:57:49.39ID:/Sdg/sCQ
>>945
ただの押しつけだな
うるせーバカ
レス数が950を超えています。1000を超えると書き込みができなくなります。