C++相談室 part146

レス数が950を超えています。1000を超えると書き込みができなくなります。
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/ (日本語)
2019/12/14(土) 15:13:40.23ID:PwUHvw+y
お前なぁ
x86のこと大して詳しくないのにしゃしゃり出てくるからそういう情けないこと言うはめになるんだよ
x86でstd::atomicのmemory_orderを変えてバリア付きがどういうインストラクションになるか見てみな
storeのseq_cst以外は素のmovだから(コンパイラ依存だから絶対ではない)
2019/12/14(土) 15:20:09.00ID:T/HCOnVQ
そりゃー間違ったマニュアルにしたがって実装したら間違った実装になり得る(キリ

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

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

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

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

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

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

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

>× 妥当な理由はない
>〇 妥当な理由は思い当たらない
こんなゴミみたいな煽り入れてきたからには逃げるなよ
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なんて書いてある?
マウントがどうたら気にするあまり後出しなんかしてるのはそっちだぞ
こっちはそんなこと微塵も考えちゃいねえよ失敬な
最初の口調に戻れよ
2019/12/14(土) 15:36:57.55ID:QUVSvjZy
間違えた
Xテンプレート実引数に使われる型が不完全型であっても、実体化まで評価を遅らせられる
○初期化に使われる定数式の評価を遅らせられる

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

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

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

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

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

>>892
>いいか、constexprは翻訳時定数だぞ
>それを翻訳段階9まで未解決のままにできると思うか?
>なんかとんがってんな
>後出しなんかしてるのはそっちだ
>余計な飾りをとって問題の核心を指摘したんだよ
さらには
>最初の口調に戻れよ
の上で
>技術的な議論がしたいがこいつ相手では
>不必要にイラついちまって無理だわ
よくそんなセリフが言えたもんだ
自己評価高すぎじゃない?wwww
2019/12/14(土) 17:52:18.36ID:SZLGcxYz
意見が合うとか合わないとか以前の問題
根底的なメンタリティに欠陥がある相手とは話にならない
2019/12/14(土) 17:58:45.99ID:k5kIl1RN
FYI

>>846
Bug 68012: g++ incorrectly accepts forward declaration of constexpr variable template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68012

>>848
One definition rule
https://timsong-cpp.github.io/cppwp/n4659/basic.def.odr#1
> No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
2019/12/14(土) 18:08:23.02ID:QUVSvjZy
>>895
わざわざありがとう、やっぱgccのバグだったのね
2019/12/14(土) 19:50:50.54ID:UskLmxJI
GCCに踊らされてスレを浪費した
2019/12/14(土) 20:04:04.94ID:4qfYuBec
>>837
オーバーロード=多態性じゃないんで…
オーバーライドのことなら当然cで実現できる
2019/12/14(土) 21:11:37.22ID:zf7JKoX1
>>898
どうやって?
いや、ディスパッチの方法はいろいろあると思うが
2019/12/14(土) 21:15:53.72ID:SZLGcxYz
禿もそんなことを言いながら
virtualの導入には当初反対から出発したんだよな
2019/12/14(土) 21:26:53.87ID:00Pm6Tju
>>899
その話題QZ相手にやったばかりなんで自分で調べて
902デフォルトの名無しさん
垢版 |
2019/12/15(日) 09:10:03.56ID:LATD77rz
君が忘れた腕時計見つめながら。
2019/12/15(日) 10:29:35.56ID:ir8W/KPm
>>898
overload は、同じ関数名で仮引数の型が違う関数を作れるという多態性のことですよ。
904デフォルトの名無しさん
垢版 |
2019/12/15(日) 10:52:20.53ID:LATD77rz
ツリーのイテレータがあるとして、イテレータが返すのはノードじゃなくて、ノードの持つ値ですよね?
すると、イテレータは立体機動出来ないといけなくなるけど、begin().begin()とか変ですよね?
begin().parent()とか。
905デフォルトの名無しさん
垢版 |
2019/12/15(日) 10:59:28.89ID:LATD77rz
イテレータが返すじゃなくて、イテレータの逆参照が返すかな。
2019/12/15(日) 11:08:51.65ID:fGq+HT2S
コレクションとしては子孫ノード全部を列挙できればよくて、ツリー構造に沿った操作が行いたいなら
それに加えて直接の子ノードのみを列挙するイテレータが用意できればいいだろう。
907デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:17:54.16ID:LATD77rz
何が子ノードのみを列挙するイテレータを返すかがよくわからない。
ノードの値がイテレータを返すことはできないので、ノードが子ノードを指すイテレータを返すとすると、イテレータの逆参照はノードを返すことになる。
これは意味論的にちょっと違うかなって。
コレクションにおいて位置はイテレータで示されるので、立体的な位置を持つツリーでは、イテレータ自身が立体機動出来て、巡回能力を持つイテレータは、reverse_iteratorのように外部に用意されれば良いのかなと思ったんだけど。
たとえば、レベルオーダーや深さ優先の巡回イテレータがあるとすると、普通に考えるとスタックやキューが内部に必要にある。
というわけでコピーのコストがあるので、これを標準には出来ないんじゃないかなって。
908デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:22:50.93ID:LATD77rz
子ノードを指すイテレータの逆参照が子ノードを返すとすると、*node.begin()は子ノードを返す。
**node.begin()は最初の子ノードの値を返すことになるんだけども。
イテレータの逆参照がノードを返す場合、初期化子リストが素直に実装出来てイイんだけども、イテレータの逆参照が値を返さないのが腑に落ちない感じ。
2019/12/15(日) 11:23:28.40ID:Q+saMC6e
>>903
こらこらoverloadは多態じゃない多重定義だ
多態はpolymorphism間違えるな
910デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:27:25.99ID:LATD77rz
イテレータは演算子の実装を求められてるわけではなく、その演算子を呼び出した時の効果を求められてるだけなので、++(int)はスタックをコピーしない方法を考えた。
2019/12/15(日) 11:30:57.88ID:fGq+HT2S
そこは値じゃなくてノードを返すイテレータでいいんじゃね?
必要ならイテレータ自体を拡張してもいいだろうけど、この場合はあまり応用できそうもないし。
912デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:31:53.05ID:LATD77rz
そうなのかな?
2019/12/15(日) 11:37:55.15ID:PfQY9kAx
まずイテレータで何を抽象化したいかを明確にしなよ
ノードを意識させたいのか?
914デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:38:38.78ID:LATD77rz
STL風ツリーって検索しても絶対出てこないし、CIAが絡んでるような気がしてきた。
915デフォルトの名無しさん
垢版 |
2019/12/15(日) 11:39:36.48ID:LATD77rz
そこがわかんないんだよねえ。
禿4とか読んでると、イテレータは位置を意味してるように思うんだけど。
2019/12/15(日) 11:45:00.74ID:mSzJWPy5
ツリー構造
範囲が広すぎて
汎用化すると使い勝手が悪くなるからしない
ってだけかと
2019/12/15(日) 11:56:45.76ID:Q+saMC6e
recursive_directory_iteratorとかね
2019/12/15(日) 12:06:14.82ID:mSzJWPy5
なんでdirectory?
treeでいいじゃん
2019/12/15(日) 12:22:05.91ID:Q+saMC6e
いや立体がどうたら言ってるから
じゃあrecursive_directory_iteratorを使うユーザーのコードは
いちいち多重ループだの再帰だのといった処理になるのかって
思ってさ
920デフォルトの名無しさん
垢版 |
2019/12/15(日) 12:24:23.41ID:LATD77rz
ツリーは、あるノードの親が知りたいときもあるはず。
2019/12/15(日) 13:07:24.45ID:TeOOTcIs
ごちゃごちゃ考える前にイテレータの本分を決めなよ
begin()からend()まで++で走らせた時にどうなってほしいの?
話はそれからだ
2019/12/15(日) 13:09:44.18ID:MBW+LfoG
一般にtreeの探索順序はアルゴリズムと深く結びついてるし、
そこ凝りだすと沼だぞ。
923デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:09:51.26ID:5G1zfwod
関数ポインタをシリアライズしてファイルとして保存し、
ファイルからその関数ポインタを利用できる形に復元する方法ってあるのでしょうか?
2019/12/15(日) 13:13:54.57ID:nhcuVJi8
関数だろうが変数だろうがポインタはただの整数値でしょ
2019/12/15(日) 13:18:39.25ID:p2D9PeH2
>>923 環境や「利用」の仕方を具体的に限定すればやりようはあるかもね。
2019/12/15(日) 13:20:48.30ID:hicN34V0
次に(別のプロセスで)ファイルを読み込んだときに、
元の関数を同じ番地で参照できると限らんしな。
関数ポインタの配列のインデクスなら大丈夫だろうだけど。
927デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:23:00.95ID:LATD77rz
https://ja.cppreference.com/w/cpp/iterator/reverse_iterator/operator%3D
これconstexprになってるけど、どういうときに定数になるんだろ?
end()の時かな?
2019/12/15(日) 13:39:23.84ID:2FA7t6Jx
C++20以降のvector/stringとか
使われる時にconstexprであることを妨げないようにするために付いてるんだと思う
929デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:47:38.10ID:LATD77rz
どうもありがとう。
2019/12/15(日) 13:52:49.06ID:ph9lwYgM
constexpr関数の中で使うため。
931デフォルトの名無しさん
垢版 |
2019/12/15(日) 14:30:37.97ID:o9m7qUoD
デストラクタがデフォルトでvirtualじゃないのは設計不良ではあるまいか
2019/12/15(日) 14:34:47.01ID:EeC59mXx
あえてベースの方のメソッドを呼びたいなんてことあるのかね?
2019/12/15(日) 14:38:17.75ID:p2D9PeH2
>>931 https://isocpp.org/wiki/faq/virtual-functions#virtual-dtor-rationale
2019/12/15(日) 15:15:03.49ID:K1ul1r/C
>>931
C++では基本的にゼロコストでできるところはそうできるようにするポリシーだからvirtualが必要なときだけvirtualを明示的に指定させる、というのをどこかで読んだ気がする
2019/12/15(日) 15:29:48.68ID:7Mmj/dyw
virtualでなかったら継承禁止にしても良かったんじゃないかとは思う
2019/12/15(日) 16:19:56.16ID:AolOnHel
そうするとメタプログラミングに色々と支障が出たはずだし
STLも結構継承使ってるから実現出来なかったかコスト増えてるよ
2019/12/15(日) 16:52:10.11ID:TkLVy9px
デストラクタをvirtualにする必要があるのは、baseのポインタ経由でdeleteする場合だけ
baseのポインタを使うことすらないようなもの(CRTPなど)までvirtualになるのは
どうなんだろうか
2019/12/15(日) 17:01:04.52ID:ph9lwYgM
unique_ptr使えばvirtualにする必要無いのでは?
2019/12/15(日) 17:16:05.58ID:p2D9PeH2
>>938 んなこたーない。
shared_ptr<Base>{new Derived} なら virtual デストラクタ不要になるから、間違えて覚えてるだけでは?
2019/12/15(日) 18:59:53.87ID:tmrMX5L5
>>937
>デストラクタをvirtualにする必要があるのは、baseのポインタ経由でdeleteする場合だけ
mjk、
2019/12/15(日) 19:10:50.35ID:AolOnHel
セオリーとして覚えてる人多いけど、何故なのかまで考えてない人が多い例の一つだね
要するにdeleteする基底のポインタからデストラクタを呼ぶ際に末端のデストラクタを呼ぶ方法(vtable)が必要というだけ
末端のデストラクタを呼べれば、そこから基底のデストラクタを呼んでいくのは何が基底かわかりきってるから自動で出来る
2019/12/15(日) 19:29:34.24ID:tmrMX5L5
>>941
>基底のポインタからデストラクタを呼ぶ際に末端のデストラクタを呼ぶ方法(vtable)が必要というだけ
mjk、
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
2019/12/15(日) 20:01:24.23ID:01f7hQnX
>>943
ラムダ式の出番かな?
void test(bool flag) { flag ? []{ for(int i = 0; i < 10; ++i) cout << i; } : throw 1; }
2019/12/15(日) 20:05:17.27ID:5sPbacoo
エラストテネス
6n+1, 6n+5だけ保持とかってみんな考えるよね

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

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

~Derived() はコールされるんですね... 確認してみて驚きました。
これができる仕組みを誰か教えてください。
スマートポインタのオブジェクトは子クラスの事何も知らないのに
どうして ~Derived() のコールが可能なのでしょうか?
2019/12/15(日) 21:07:41.82ID:2FA7t6Jx
>>949
いわゆるtype erasure
https://blog.cryolite.net/entries/2006/01/08#p1
2019/12/15(日) 21:19:04.13ID:TKBas8kS
>>950
まだ仕組みのとこまでですが理解できました。ありがとうございます。
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)と書く
2019/12/15(日) 21:39:08.56ID:tmrMX5L5
ふとオモタがインスタンスの必要性は無くせるかもしれん
Foo::Bar型のメンバFoo::yが定義さえされておれば、Fooのインスタンスが無くても
 sizeof(((Foo*)0)->y)
と書けばC言語で逝けるかもしれん…
スゲー気持ち悪いコードだが、、、、
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のデストラクタは呼ばれない
2019/12/15(日) 21:48:17.68ID:5sPbacoo
なんでそんな中途半端な機能を
わざわざコストをかけて入れたんだろう
2019/12/15(日) 21:49:32.31ID:5sPbacoo
やむを得ず
なんだろうけど
2019/12/15(日) 21:51:55.29ID:PfQY9kAx
>>953
Linuxカーネルとかそういう感じのマクロ満載だよ
C言語はそういうもん
2019/12/15(日) 22:05:12.60ID:TeOOTcIs
type erasureと相性悪いんだっけ
2019/12/15(日) 22:15:04.90ID:jthcUe0A
>>943
思い出した。
gcc や clang の拡張で良ければ複文が式になる。
だいぶん昔からある機能。

#include <vector>
#include <iostream>

int main() {
std::vector<int> foo(({int i; for(i=0; i<3; i++); i;}));
std::cout << foo.size() << std::endl;
return 0;
}
2019/12/16(月) 19:39:21.34ID:NZyGx79l
>>944,945,948,959
コメントありがとうございます!

>>944,959
まずgcc拡張
>SieveDerived(int n) : Sieve<T>(({int r; while((r = index(n)) == 0) n--; r;})) { } /* HERE!! */
で問題なく動作しました
すでにgcc拡張で存在するところからみて、私の希望はあながち無謀かつ無稽なものではないことを知りほっとしました
次にラムダ式で定義して即評価する方法がみつかりました
>SieveDerived(int n) : Sieve<T>([](int n)->int{int r; while ((r = index(n)) == 0) n--; return r;}(n)) { } /* HERE!! */
これがやりたかった!とても満足しています、ありがとうございました!
今までは関数オブジェクトの糖衣構文としてしかみていなかったラムダ式を、自分の希望にあわせて(あるいはねじまげてでも)採用し、表現できるようになったのは一歩理解が深まったかと考えています

>>948
>初期化リストの中にそんなごちゃごちゃしたこと書きたい?
クラスのメソッド=メンバ関数には、クラスの提供する機能として独立性の高いもの、少なくとも二箇所で同じような処理がダブっているもの、あるいは主観的には「lemma」として成り立つものを書きたいと考えていました
一箇所でしか使わないものでも lemma 性があるのならば private メソッドとして書くのもありかと思っていますが、今回の場合は、他におなじような処理をおこなっている場所はなく、かといってメソッドとして立てるほどのことでもないので、
複数個所からコールできるメソッドにはしたくなかった、という主観がありました、そういう性質の記述ならば初期化リストにごちゃごちゃ書くのもありかと、読み手には他からコールされ得ないことが自明である点からしても

https://ideone.com/y3ROXS
2019/12/16(月) 20:14:24.13ID:89loOkbp
まあこういう自己満は通過儀礼だよな
2019/12/16(月) 21:46:21.90ID:kSgVv2yp
lambdaの即時評価はjsだと多用されているイメージ
ブロックスコープないからね
2019/12/17(火) 00:52:53.01ID:0JRJucIS
>>960
> すでにgcc拡張で存在するところからみて、私の希望はあながち無謀かつ無稽なものではないことを知りほっとしました

30 年以上の実績があってもなお仕様に入らない程度に駄目なんだよ。
964デフォルトの名無しさん
垢版 |
2019/12/17(火) 03:23:09.50ID:JQ5aWxOy
プライベートメンバの単体テストってみんなどうしてるのかな。
2019/12/17(火) 03:30:02.23ID:nsTCJN+n
#define private public
2019/12/17(火) 03:58:13.47ID:KUtZUPl9
#if 0
friend test;
#endif
2019/12/17(火) 07:08:07.08ID:KzMqUd+t
#ifndef NDEBUG
friend struct test;
#endif
2019/12/17(火) 07:46:15.26ID:wpWnXFFo
闇言語
969デフォルトの名無しさん
垢版 |
2019/12/17(火) 11:20:07.09ID:dc1/89bE
namespace Method{ namespace Detail {
template<typename ReturnType, typename ... ArgTypes> struct MethodRegister{};
} }
// 文字列で呼び出すための関数を登録するためのマクロ
#define METHOD_REGISTER_WITH_NAME( NAME, FUNC, RETURNTYPE, ... ) \
namespace Method { namespace Detail { \
template<> struct MethodRegister<RETURNTYPE, __VA_ARGS__> { \
using Functional = std::function<RETURNTYPE(__VA_ARGS__)>; \
MethodRegister() { \
MethodContainer::GetInstance().Register<RETURNTYPE, __VA_ARGS__>( #FUNC, Functional( static_cast<RETURNTYPE(*)( __VA_ARGS__ )>( FUNC ) ) ); \
} \
~MethodRegister() { \
MethodContainer::GetInstance().Unregister( #FUNC ); \
} \
}; \
static MethodRegister<RETURNTYPE, __VA_ARGS__> sMethodRegister##FUNC; \
} }
void HOGE(){
std::cout << "Hello World!" << std::endl;
}
void HOGE( std::string text ){
std::cout << text << std::endl;
}
METHOD_REGISTER_METHOD( HOGE, void );
METHOD_REGISTER_METHOD( HOGE, void, std::string );

こういった形で関数を登録する用のクラスを生成し、変数として生成して管理の自動化を行いたいのですが、
関数のオーバーロードを対応しようとした所、クラスの再定義や変数の再定義、管理クラスへの重複登録等
多数の問題が出て詰まってしまいました。
こういった問題を対処するにはどうすればよいのでしょうか?
970デフォルトの名無しさん
垢版 |
2019/12/17(火) 11:28:10.65ID:rApV4krM
BOOST
2019/12/17(火) 12:23:52.67ID:lfJGbKnI
>>966
>>967
リリース時に消す必要あんの?
2019/12/17(火) 18:42:08.59ID:iYSb7MEE
このへんがいいんでないの。
https://srz-zumix.blogspot.com/2015/06/c-private.html
2019/12/17(火) 19:10:07.01ID:780pCLgH
>>963
まあ、
({int r; while((r = index(n)) == 0) n--; r;})
の最後の
r;
というのが限りなく非文法的ですし
2019/12/17(火) 21:19:56.70ID:r3fDxRx7
プライベートメンバをテストしたくなったらそのロジックのみを非メンバ関数に切り出してテストしてるな。
まぁ、特に支障がなければ単純にpublicにするだけの時もあるけど。
2019/12/17(火) 21:45:39.29ID:HvtzVY9o
templateでアクセスすると合法的にプライベートメンバにアクセスできる
2019/12/17(火) 21:49:21.80ID:iYSb7MEE
そんな糞な方法でテストなんかしたくねー。
2019/12/18(水) 01:14:03.75ID:zSYbFuJ0
テストなんかお綺麗にする必要が無い
2019/12/18(水) 06:18:11.97ID:BbfJ/y//
テストのテストが必要になるような意味のわからないテストコードはアウト
テストコードは実行せずに人が読んで理解できなければいけない
979デフォルトの名無しさん
垢版 |
2019/12/18(水) 07:25:56.60ID:ksLRDXXy
>>978
どんな感じか見せていただけないでしょうか。
2019/12/18(水) 07:42:51.80ID:PEFQbiIG
>>971
絶対必要でもないが
少なくともデバッグ用であることくらい
アピールしたい
//よりNDEBUGという特定ワードを使う点にも拘りがある
レス数が950を超えています。1000を超えると書き込みができなくなります。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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