C++相談室 part145at TECH
C++相談室 part145 - 暇つぶし2ch457:
19/10/13 01:16:58 Fwjkj11x.net
LTOは本当のリリース時や速度検証の時以外は外しても問題ないよね

458:デフォルトの名無しさん
19/10/13 09:37:54.86 kfwaB+Y7.net
ここの話で出ている
>296
>>294
clangさんが教えてくれた
std::string hogehoge() { return A<_T3>::template get<std::string>();}
>436
c++言語の場合、パースのコンテキスト依存が、識別子の種類でも変わるから、
テンプレート時の記述でtypename やらtemplateやらで、
識別子の種類自体を指定する羽目になっているのはあるよね
<_T3>::templateやtypenameをどの様な場合に書かないといけないのか?
この辺を解説した初心者向けか入門者向けの解説サイトみたいな所が
何処かに有りませんか?
サイトが無さそうなら検索に向いている単語みたいなのでも有れば助かる
::templateとかで検索しても上手く引っ掛からないみたい(有るには有るけど少ない)

459:デフォルトの名無しさん
19/10/13 10:06:17.74 zTi0Tc1S.net
コンパイラが出すメッセージで検索してみれば?

460:デフォルトの名無しさん
19/10/13 11:14:46.72 Fwjkj11x.net
>>454
URLリンク(ja.cppreference.com)

461:デフォルトの名無しさん
19/10/13 17:23:21 Y0ptPfKA.net
他の言語で書かれたコードをスクリプトの要領で
C++から呼び出して実行したいのですが、
そういった事をするのに適した言語ってどういった物があるのでしょうか?

462:
19/10/13 17:23:50 Y5pFrXym.net
>>457
パイソン

463:
19/10/13 17:31:01 9auzzyVZ.net
言語間のABIの違いを透過的にしたいのならアセンブラの出番だね

464:
19/10/13 17:36:26 1+8oai62.net
まさにそういう用途で作られたluaとか

465:デフォルトの名無しさん
19/10/13 17:44:25.71 j3fG3YC6.net
>>457
今ならluaかjs(V8/ChakraCore/SpiderMonkey)だな。
【Lua】組み込み系言語総合 その7【Squirrel】 [無断転載禁止]©2ch.net
スレリンク(tech板)
pythonもできなくはないけど手軽とは言えない。
pythonを使いたい理由がなければやめておくのが吉。

466:
19/10/13 18:10:48 pJwii1Hg.net
pythonは呼ぶ方で、呼ばれる方としてはほとんど想定されてないわな。

467:
19/10/13 19:05:43 m8H1BiEu.net
lua以外無い

468:
19/10/13 19:35:48 rjz838Ki.net
>>457
tcl

469:デフォルトの名無しさん
19/10/13 20:24:22.36 kfwaB+Y7.net
>455,456さんどうもです
エラーが出たらそうしてみます
リンク先を読んで見ましたが
自分には難しいのでそのページを手がかりに検索して(依存名で探してみた)
漸く理解出来た気がします
前にstd::を付ける付けないって話を何処かでしてい
自分的にはどうしたものだろうか?
って感じだったんですけど
adlやtwophasenameとかの解説と合わせて書いて有るのを呼んでいて
std::を付けるのはかなり重要なんだと思えてきた
今までnamespaceって単なるグループ名を付けている
くらいの感覚だったんですけど
意外と重要なんですね
どうもでした

470:デフォルトの名無しさん
19/10/14 15:05:53.73 rfaLGQBa.net
template<size_t N>
class Test{
public:
private:
int m[N];
};
上の様なクラスでコンストラクタでmを値を指定して初期化したいんだけどNの数は未定ではないですか。
こういう場合のコンストラクタの書き方ってどうすればいいのでしよう?
可変引数?

471:デフォルトの名無しさん
19/10/14 15:12:05.32 BPBGG2nS.net
コンパイル時に決まってないならvectorかなんかにするしかない

472:デフォルトの名無しさん
19/10/14 15:18:08.00 P81x9Tjl.net
templateパラメータの整数にはコンパイル時に決まらない数値は入れられない

473:デフォルトの名無しさん
19/10/14 15:28:00.19 qN7fFVrS.net
>>466
そもそも、そのような生配列は、デフォルトでは0初期化もされないので、
メンバ初期化子リストを使わなくても効率は落ちないので、
コンストラクタ内部で普通に代入演算子を使って初期化すればいい。
すると、単に任意個数の引数をコンストラクタに渡す問題になる。
それには、昔ながらの va_list を使って渡す方法と、
関数テンプレートやテンプレートクラスを使って、自分自身を一つずつ引数を
減らしながら呼び出していく方法の二通りある。

474:デフォルトの名無しさん
19/10/14 15:28:52.79 Y7o3BEyU.net
>>466
Test(std::initializer_list<int>&& arg)
{
std::copy_n(std::begin(arg), N, std::begin(m));
}

475:デフォルトの名無しさん
19/10/14 15:30:45.59 rfaLGQBa.net
>>469
一度考えたのはテンプレートの可変引数なんですが
//Testのコンストラクタ
template<typename... T>
Test(T... args):m{args...}{
}
templateの可変引数の為にどんな型でも一致してしまい、そのくせにdoubleからintなどの変換をしてくれないのでinitializer_listを引数に出来たり、もしくはもっといい初期化方法があるのかなと思った次第です。

476:デフォルトの名無しさん
19/10/14 16:18:31.70 1VO4fG6M.net
URLリンク(ideone.com)

477:
19/10/14 16:48:34 REdvl5Gt.net
>>471
>そのくせにdoubleからintなどの変換をしてくれないので
この点に関しては、以下の拡張展開でいけるはず。
template<typename... T>
 Test(T... args):m{((int)args)...}{
}

478:
19/10/14 16:55:25 REdvl5Gt.net
templateの「非型引数」を使えば、理論上は、
template<int...args>
Test(int...args):m{args...}{
}
と書ける可能性はあるかもしれないけど、試してみてないので分からない。

479:
19/10/14 17:04:44 REdvl5Gt.net
C++11 から、template 仮引数(パラメーター)に非型パラメーターパックが使える。
分かっているとは思うけど、このパックとは可変長引数をまとめて入れる容器の様な意味。
実際にやってみてないのでわからない。

URLリンク(en.cppreference.com)

【Non-type template parameter】
type ... name(optional) (3) (since C++11)
3) A non-type template parameter pack with an optional name.

480:
19/10/14 17:48:47 DdI7aqm2.net
>>466
要素数がコンパイル時に決まってるなら std::array 使って Test<3> x{{1,2,3}} とすることは簡単にできそう。

481:デフォルトの名無しさん
19/10/14 20:20:29 ljIrzJ7B.net
>>464 >>457
tcl + 1

482:デフォルトの名無しさん
19/10/16 00:49:52 4OT/K/L6.net
>>473 Thank you!!

483:
19/10/18 03:20:02 kbBE7aSe.net
他クラスのメンバ関数テンプレートを呼び出すときってtemplateキーワードを関数名の前に付けないと
operator<と間違われてエラーになりますですよね?具体的に例をあげてみますと

URLリンク(wandbox.org)

これの t.template func<T2>(); のところですが、実はこのtemplateキーワードを外しても
WindowsのVisualStudioだとコンパイルが通ってしまいます。
これってVisualStudioが規約違反しているという理解で合っていますか?

484:デフォルトの名無しさん
19/10/18 03:32:35.18 L8qU11hp.net
vsのバージョンは?
2017の途中からtwo phaseに対応しだしてtemplate周りの怪しい挙動は大分改善された

485:
19/10/18 11:35:03 kGqx1xn0.net
>>480
Express 2017 for Windows DesktopとProfessional 2019で確認しています
準拠モードを「はい」にしたら標準の規約に従うのかと思ったんですが変化なしでした

開発はWindowsでしつつもWindowsとLinuxどちらでもコンパイルできるようにしたいんですが
もしかしてそう簡単な話ではないんですかね

486:
19/10/18 12:11:07 8CoI4J3v.net
>>481
visual studio cmakeプロジェクトでググる

487:デフォルトの名無しさん
19/10/18 15:49:49.04 /qIwU54Z.net
effective modern c++のnoexceptの項読んで思ったんだが、
C++の関数内でCの関数(具体的にはOpenGLとか)を呼び出した時に
C++側でcatchできる例外って具体的にどんなものがあるの?
試したことないけどmalloc失敗でbad_allocは飛ばないよね?

488:デフォルトの名無しさん
19/10/18 18:57:22.15 eJANlQqR.net
Windowsなら構造化例外とか

489:デフォルトの名無しさん
19/10/18 19:16:01.68 rTjJuJDg.net
>>482
cmakeってビルドに関するものだったような?
ソース自体はWindowsとLinuxで完全同一にしたいんですが
あれなんか自分勘違いしてるかな
とりあえずcmakeくぐります、有難う

490:デフォルトの名無しさん
19/10/18 19:19:00.58 5559SrY6.net
VCコンパイラがWindows専用だからcmakeだけでは解決しない
clangオプション使えばいけるんじゃね

491:デフォルトの名無しさん
19/10/18 19:27:02.65 BPo3Wxa0.net
cmakeってなんとなくしか使ってないんですけど何なんですか
OpenCVのソースをビルドするときに使いましたけど、cmakeした後にまたVisual Studioでコンパイルする必要があるのはなぜですか

492:デフォルトの名無しさん
19/10/18 21:38:24.25 1VxWd/yq.net
>>487
cmakeってmakeの代用じゃなくてmakefileとかxxx.slnとかを作るソフト
なのでcmake実行後に各々の環境にあったビルドを行う

493:デフォルトの名無しさん
19/10/18 22:32:33.72 HsDKWWc7.net
>>487
ビルドするためのスクリプトを作るツール、みたいに考えるといいよ
linux環境ならLinux用のものを作ってくれる
makeだと基本はlinux専用だし、.slnや.vcxprojはwindows専用だから、両方を面倒見るのは大変でしょ

494:デフォルトの名無しさん
19/10/18 22:48:18.41 f2FG8XiO.net
ビルドするためのスクリプトを作るためのスクリプトを作るためのスクリプトなんてよくある話だよ。

495:デフォルトの名無しさん
19/10/18 22:49:57.04 a3uRi/Ig.net
秘伝のタレな

496:デフォルトの名無しさん
19/10/18 23:06:23.18 liCy40EB.net
GNU autotoolsをまともにいじる輩は消え去ったという現実をcmakeも味わうことになる。
バカは同じ間違いをする。歴史も見ずに。

497:デフォルトの名無しさん
19/10/19 00:19:02.04 JKxr+RAJ.net
CMakeってKitwareっていう大学発ベンチャーから出てきたやつだよな
もとはVTKとか可視化用ライブラリ開発してるしがないベンチャーだったのに
CMakeのおかげでやたら顔が知られるようになった

498:デフォルトの名無しさん
19/10/19 00:40:35.72 kiA3Djjo.net
VTKとparaviewの方が有名じゃなかったのか

499:デフォルトの名無しさん
19/10/19 00:44:42.31 JKxr+RAJ.net
ParaViewは最近になって有名になってるけど所詮はVTKのラッパーでしょ
CMakeのほうが影響度はでかいと思う
ベンチャーでここまでやれたなら大成功な事例だね

500:デフォルトの名無しさん
19/10/19 00:58:43.11 kiA3Djjo.net
cmakeより前から有名じゃね?

501:デフォルトの名無しさん
19/10/19 01:00:35.87 4XSJxZBk.net
cmake邪魔くさい
Makefile.am, configure.acからautoreconfしてconfigure作る方が楽。
windows用もmingwでクロスビルドしちゃえば楽だし。
WSLでwindowsからも見えるパスでビルドすると作ったwindows用binaryをすぐに起動できるしいうことなし

502:デフォルトの名無しさん
19/10/19 01:28:27.26 kDntEbbb.net
mingw使わずに標準のwindowsの環境で使えるようになってから出直してきて

503:デフォルトの名無しさん
19/10/19 01:36:12.28 +xsHXYvs.net
mesonいいぞー

504:デフォルトの名無しさん
19/10/19 01:37:16.21 JKxr+RAJ.net
makeとかのビルドツールって超重要なはずなのにおざなりな状況になってるのは不思議だ
なんとかしてくれ

505:
19/10/19 01:49:35 kiA3Djjo.net
クロスプラットフォームなソフト作るにしても、成果物が対象の環境で動けば良い訳で、ビルドをどの環境でも出来ることにそれほど意味はないからね
てかunix系でgccやclang使って開発しているものをVCに入れても謎の独自仕様でコンパイルできないとかザラだしね

506:デフォルトの名無しさん
19/10/19 04:05:50.65 kDntEbbb.net
>>500
そう言って立ち上がった人は100億人くらいいたが誰一人として帰ってくる者はいなかった

507:デフォルトの名無しさん
19/10/19 04:25:19.36 Qviva8VV.net
>>502
ほんとこれw

508:
19/10/19 07:26:21 4XSJxZBk.net
>>498
wslでmingwクロス環境はマクソ提供だけど

509:
19/10/19 09:24:58 wYu0/eCZ.net
あらゆるビルドツールは怪獣化して、怪獣を飼いならすためのラッパーが必要になり、そしてそのラッパーももれなく怪獣化する
歴史が証明しており例外はない

510:
19/10/19 09:25:25 WQwZNfDO.net
会社でifstreamのファイルオープンがエラーになるのはなぜなのか不明。assert()で引っかかる。
Visual Studio 2008コマンドプロンプトでコンパイルしたプログラムで、コードは単純化
して示したものが下記のようなもの。
std::ifstream ifs1;
for (n = 0; n < 8; ++n) {
ifs1.open(s[n].c_str());
assert(ifs1); // もしくはassert(ifs1.is_open());
関数(ifs1);
ifs1.close();
ifs1.clear();
}
コーディング上に間違いがあるのかいな。ファイルが使用中のためにエラー
でもないようだし。
よくわからんからCのFILE *に変更して対処したけどコンパイラの欠陥か。
ifstreamを宣言した後に ifs1.clear(); が必要なのか。

511:デフォルトの名無しさん
19/10/19 09:50:39.86 wYu0/eCZ.net
ifsreamってcloseの後に再使用できる保証あったっけ?
ifs1の宣言をfor文の中に入れて毎回オブジェクト作り直す方が無難に見える

512:デフォルトの名無しさん
19/10/19 09:51:32.93 wYu0/eCZ.net
宣言じゃないや定義

513:デフォルトの名無しさん
19/10/19 09:54:59.18 Xn59Im0u.net
makeが複雑なんじゃなくて
多様な環境すべてに対応するように書くことが複雑なわけで。
だったらdockerなり使って一つの環境だけでの提供を考える方が楽。

514:デフォルトの名無しさん
19/10/19 11:50:11.90 Xq/UOX2V.net
>>506
まずファイル開く権限あるのかな
最近それで引っかかった

515:デフォルトの名無しさん
19/10/19 12:33:25.60 IyvFodwr.net
>>484
あれ、Winの構造化例外ってそもそもtry..catchには引っかからなかったような……

516:デフォルトの名無しさん
19/10/19 12:41:43.65 IyvFodwr.net
Rakefileを使っている俺は小数派。
>>506
古いVCの場合ifstreamのclear()後再使用はできなかった記憶がある。

517:デフォルトの名無しさん
19/10/19 13:51:45.42 2wK0PqU+.net
C++でv8のjavascriptを使うために
インストールしようと色々やってるんだけどどうにもうまく行かない。
URLリンク(qiita.com)
このサイトを参考にしながら進めてるんだけど
「depot-toolsインストール」の環境変数を通す項目で
C:\v8\depot_tools\win_tools-2_7_6_bin\python\bin
このパスがダウンロードしてきたdepot-toolsにはないんだけど、
どこにあるか誰か知りませんか?
スレチだったらごめんなさい。

518:デフォルトの名無しさん
19/10/19 14:48:33.14 g7gJ/kc1.net
おま環
何をダウソしたかくらいは書け

519:デフォルトの名無しさん
19/10/19 15:03:15.21 g7gJ/kc1.net
python2.7 が既に入ってるなら
その bin に path 通しとけば良いんかな

520:デフォルトの名無しさん
19/10/19 15:14:23.88 Q3nSZoDU.net
>>483
C の関数が呼び出すコールバックを C++ で書いた場合、環境によってはコールバックからの例外が
C の関数を通過してくる。環境によっては通過できずに terminate() するけど。
厳密に「Cの関数」じゃなくなるけど qsort(), bsearch() については例外が通過できるものと規定されている。
あとは未定義動作となる場合の反応として例外が飛んでくることはあるかもしれない。

521:デフォルトの名無しさん
19/10/19 15:22:29.09 2wK0PqU+.net
>>514
忘れてた。スマヌ。
Windows10 X64
Visual Studio Community 2019
Python 3.7.4(64-bit)
Git version 2.23.0.windows.1
ダウンロードしたのは
URLリンク(chromium.googlesource.com)
ここから「x64 Native Tools Command Prompt for VS 2019」
で「git clone」を使ってダウンロードしました。
>>515
python自体のbinフォルダは試してませんでした。
ちょっとやってみます。

522:デフォルトの名無しさん
19/10/19 15:27:23.69 g7gJ/kc1.net
OS とかツールは全部違うけど
URLリンク(chromium.googlesource.com)
これ clone しても確かに win_tools-2_7_6_bin は無かった

523:デフォルトの名無しさん
19/10/19 15:29:04.62 ydKYIai+.net
何故公式のインストール手順を読まないのか

524:デフォルトの名無しさん
19/10/19 19:15:58.17 fDUUZQql.net
Node.js じゃ、ダメなのか?

525:デフォルトの名無しさん
19/10/19 20:05:28.35 +xsHXYvs.net
>>511
なんか設定次第で引っかかるようにならなかったっけ・・・

526:517です
19/10/20 17:45:24.74 njFFTJVf.net
>>519
インストール手順自体は試したんだけど、
あまりに訳わからんちんで途中で断念して
他のサイトを見ながら入れようとしています。
>>520
Node.jsってv8の上に乗っかったjavascriptというイメージなんだけど、
C++から呼び出せるのでしょうか?

527:
19/10/20 20:19:16 hyX4MvIl.net
今、YappyCamという録画ソフトを作っています。以下のソースをご覧下さい。

URLリンク(github.com)
URLリンク(github.com)
URLリンク(github.com)

このSoundが音声を扱うクラスになっております。
スレッド関数Sound::ThreadProcで録音処理を行っています。
std::vector<BYTE> m_wave_dataがサウンドバッファです。
Sound::FlushDataがバッファを吐き出す関数です。

現在、SSDが主流になりつつありますが、ハードディスクでもトラブルなく使えるようにしたいです。いくつか質問します。

1.m_wave_dataをstaticな固定バッファにすべきか。するとすればどれぐらいの容量か。
2.もっといいバッファリングの方法はないか。

お願いします。

528:蟻人間
19/10/20 21:02:47.12 hyX4MvIl.net
スピード命です。フレーム落ちは絶対にダメだそうです。

529:デフォルトの名無しさん
19/10/20 21:06:32.98 I/H74RW7.net
古臭いスタイルはさておき・・・
(別にそれでいいと思うよ)
なぜバッファリングしてる?
vectorにためずにwriteしたらいいじゃん
readとwriteの単位が合わないとか?
バッファリングするならreader/writerで別スレッドにした方がいいかもね
オーディオの処理なんだからおれなら動的メモリ確保の走るvectorは使わないね
最悪システムコールだから音が途切れる可能性が高まる
一瞬かもしれないが音は少しでも途切れるとノイズになる
最適なバッファ量はそのルーチンがどれぐらいのジッターで駆動してか計測して決めればいい
あとバッファリングすればそれだけ遅延が発生するから注意
本来ビデオ側と同期をとる必要あるけどPCだと適当だよな
CE機器だと完璧に合わせるけど

530:
19/10/20 21:15:47 PJrfugKB.net
COBOLのWRITE命令みたいに非同期書き込み&バッファローテーションてか?
あの当時のアホOSならともかく今どきアプリでそんなことせにゃならんか?
ベアメタルなら面白そうだけど

531:
19/10/20 21:16:42 Vt7fKSBc.net
遅延の原因は、vector::insert()でしょ。

532:
19/10/20 21:24:56 akKR2ina.net
ズらすの?

533:
19/10/20 21:27:13 peAHiKUT.net
誰がハゲやねん

534:
19/10/20 22:12:11 2g822Cxo.net
ああそうか。std::FILE/CreateFileそのものがバッファリングしてるんだ。ならば下手なバッファリングは必要ないと。

普通にI/Oすることにします。ありがとうございます。

535:
19/10/20 22:21:50 2g822Cxo.net
std::vectorのメモリー動的確保は音声処理では不味いと。

ハードディスク環境でジッターを測定して見ないと。わかりました。

536:
19/10/20 22:32:55 I/H74RW7.net
>>530
ただそのスレッドでwriteするのが問題ないかはよく確認した方がいいよ
writeでブロックされることで音声のソース側の処理が滞る可能性がある
その場合はやっぱり別スレッドにすべきだね

537:
19/10/20 22:59:16 2g822Cxo.net
プログラム高速化の禁術
URLリンク(qiita.com)

538:
19/10/20 23:12:22 2g822Cxo.net
setvbufって便利な関数を見つけた。これ使うか。

539:
19/10/20 23:13:52 fVQAzz8M.net
音声のバッファリングには普通はリングバッファを使う

540:
19/10/20 23:28:56 2g822Cxo.net
ここまでのまとめ。

リングバッファを使う。
十分大きなバッファサイズでsetvbufを使う。
リングバッファへの読み書きは別スレッドにする。
バッファが空のときはイベント待ちで休ませる。

541:デフォルトの名無しさん
19/10/20 23:44:50 Vt7fKSBc.net
別スレッドにキューイングするのに適したC++標準クラスは何かな?

542:デフォルトの名無しさん
19/10/21 06:50:33.92 iwcvXj42.net
ゴチャゴチャ言うならビルトイン配列使っとけ

543:デフォルトの名無しさん
19/10/21 15:01:03 c9dhXgWB.net
C++から呼べるし
C++を呼べる

544:デフォルトの名無しさん
19/10/21 15:43:44 M4XH2/Bk.net
>>537
Queue への読み書きは、1要素当たりは短時間で済むことが多いので、
Queueを読み書きする場所で、必ず Critical Section などで囲むと良い。
一度に沢山の要素をまとめて書き込みたい場合は、原則的には、
1要素を書き込む処理をこまめに、Critical Section で囲むようにする。
必ずしも1要素ずつ囲む必要は無いが、こまめに囲った方が、
別スレッドの待ち時間が減ることが期待できるが、その意味が有る場合と
無い場合とが有る。
Critical Section の代わりに、Mutex や Semaphore などを使うことも出来る。

545:デフォルトの名無しさん
19/10/21 17:


546:20:19.00 ID:Yxovtd3S.net



547:デフォルトの名無しさん
19/10/21 18:19:39.76 iwcvXj42.net
タイミングで問題が出てるのにvectorにこだわるのはアホだよな

548:デフォルトの名無しさん
19/10/21 18:33:52.73 K8Ck/3Ch.net
実行時のパラメータでバッファサイズ可変にするならvectorで始めにresizeしておくのが楽
size使える分配列のunique_ptrより取り回しも楽だし

549:デフォルトの名無しさん
19/10/21 18:43:04.52 Kc9FjQwr.net
boostにリングバッファのクラスあるよ

550:蟻人間 ◆T6xkBnTXz7B0
19/10/21 18:50:23 LVq8IpRv.net
天才だから自分でリングバッファ作った。
URLリンク(github.com)

551:蟻人間 ◆T6xkBnTXz7B0
19/10/21 19:22:51 ICV7tWge.net
バッファがいっぱいになったらどうしよう?

552:537
19/10/21 19:27:27 iqf1snDW.net
>>540
それらの同期機能って標準C++のクラスだけで実現できるもんなの?

553:デフォルトの名無しさん
19/10/21 19:30:51 Kc9FjQwr.net
>>546
捨てるしかないだろ

554:デフォルトの名無しさん
19/10/21 20:56:31 NgTxqwl+.net
>>547
どこまでを標準と言ってるのか知らんけどお前の考える標準でスレッドをサポートしてるならたいてい同期機構もあるはず

555:蟻人間 ◆T6xkBnTXz7B0
19/10/21 21:02:21 LVq8IpRv.net
>>547
WindowsではCriticalSection, CreateMutexなどがあったからC++11以前でも使えた。
C++11からstd::mutex, std::lock_guardなどが使えるぞ。

556:デフォルトの名無しさん
19/10/22 00:25:01 IM/z9Y8P.net
ロックフリー的ななんか無かったっけ?

557:蟻人間
19/10/22 16:18:00.26 QN5InCe0.net
リングバッファの排他制御どうするか?
push/popごとにロックかけたら遅くなりそう。

558:デフォルトの名無しさん
19/10/22 16:36:38.23 LzjGZCpL.net
>>545
stlライクにしてる割にコピーやムーブが内部の値ベースなのおかしくない?

559:デフォルトの名無しさん
19/10/22 17:03:31.86 mzkWHCb9.net
用途的に
reader 1
wrtier 1
だと思うけどそれならwait freeな実装が可能
read pointer/writer pointerで制御するやつね
かつかつに最適化するならこれ
しかしその前にどれだけの頻度と長さで排他の衝突するか見た方がいい
リアルタイムのオーディオなら短くても5msec周期とかじゃないか
かつlock中に多少のメモリの読み書きやってるだけなら排他が必要な時間は短い
なら素朴にmutex1個でのロックで十分な可能性も高い
同期のミスはデバッグがつらいから不用意に難しいことしない方がいい
もしくはある程度のバッファリング(遅延)が許容できるとか、固定長の処理であるなら
ならバッファを複数用意してダブル、トリプルバッファ的な制御でもいいだろう
つまりwriter側でバッファに全部書き終わったらそのバッファをreader側のキューにいれる
reader側は全部読み終わったらwriter側のキューに戻す
っての
とにかく原則どおりまずシンプルにミスなく作って計測して最適化ね

560:デフォルトの名無しさん
19/10/22 17:19:01.36 mzkWHCb9.net
ringのソース見たけど
おれはm_full なしでやるのが好みだな
つまりm_front_indexとm_back_indexが一致するのはemptyのときのみ
full時には実際は1個空きがある状態
これを推し進めればwait freeの実装に近づけるぞ
車輪の再発明だが勉強にはなる

561:デフォルトの名無しさん
19/10/22 17:21:45.79 2ZhQSHmS.net
>>551
std::atomicとかあるね
原理的に競合が起きないやつ

562:蟻人間
19/10/22 17:29:01.30 QN5InCe0.net
まずは記憶媒体の性能を計測してみた。
URLリンク(github.com)
URLリンク(twitter.com)
これはSSDの場合だ。HDDでも同様に計測しないといけない。
(deleted an unsolicited ad)

563:蟻人間
19/10/22 17:43:23.84 QN5InCe0.net
static DWORD s_dwTick;
printf("write: %ld, %ld\n", cbToWrite, GetTickCount() - s_dwTick);
s_dwTick = GetTickCount();
// 最高の音質での出力。
write: 3900, 15
write: 3900, 0
write: 3900, 16
write: 3904, 16
write: 3900, 0
10msecごとに音声データがおよそ3900バイトあるようだ。

564:デフォルトの名無しさん
19/10/22 18:28:33.04 HSQTG8Jj.net
>>558
Win32APIや音声仕様はC++じゃないのでよそでどうぞ。>蟻人間

565:蟻人間
19/10/22 19:41:50.02 +0Lq2R8m.net
>>553
具体的にどうやればいい?

566:蟻人間
19/10/22 20:08:29.90 +0Lq2R8m.net
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
スレリンク(tech板)
こっちに移動します。回答者に感謝します。

567:デフォルトの名無しさん
19/10/22 21:35:58.70 SC+tqfVH.net
Win32APIって何だよ
20年前からタイムスリップでもしてきたか?

568:
19/10/22 21:43:35.88 afWm6mlf.net
>>562
win32api(64bit版)で書くのが正義、という価値観もまだまだ存在するようです

569:デフォルトの名無しさん
19/10/22 23:33:30.81 QUuuj0zF.net
C++11からできた属性構文あるけどこの属性は宣言にだけつければOK?
定義にも同じ属性を記載するべき?

570:デフォルトの名無しさん
19/10/23 00:34:15.61 kAyiuXKe.net
>>563
それはお前だけの価値観だろハゲ

571:デフォルトの名無しさん
19/10/23 00:50:12.41 /s0IRa9G.net
>>563,565
Mozilla Firefoxなどサードパーティ大手は今もWin32APIをネイティブに使っており.NETを使ってない。

572:はちみつ餃子
19/10/23 01:51:47.45 GER+FSVM.net
>>562 は .NET より WinRT とかを想定している気がするが。

573:デフォルトの名無しさん
19/10/23 02:03:48.66 my1FePPi.net
単に64bitのWindows APIもなぜかwin32と呼ばれ続けてること知らないんだろ

574:デフォルトの名無しさん
19/10/23 06:28:47.24 /lpUBik0.net
それこそ20年前からタイムスリップしたのかって話だなw

575:デフォルトの名無しさん
19/10/23 18:08:41.93 bvZ5IXVl.net
速度重視な場面ならWin32APIは今でも普通に使う

576:デフォルトの名無しさん
19/10/23 20:43:18.87 R0F6kh0V.net
うわぁ・・・

577:デフォルトの名無しさん
19/10/23 21:15:01.42 kC3TvNwV.net
正直なところWin32APIで速度でるの?

578:デフォルトの名無しさん
19/10/23 21:30:55.10 /s0IRa9G.net
>>572
「Linuxシステムコールで速度でるの?」という質問と同じくらい矛盾に満ちた質問。
Win32APIも含めシステムコールはOSが提供するAPIなので、プログラマは他の手段で代替しようない。

579:デフォルトの名無しさん
19/10/23 21:35:56.58 H9cLmi0l.net
Native APIがあるじゃろ

580:デフォルトの名無しさん
19/10/23 22:12:26.70 B7dtMHRy.net
Visual C++ 2015なんですが、
goto文でERRORというラベルに飛ばそうとしたら、コンパイルエラーが出ました。
ERRにしたらコンパイルできるようになったんですが、
なぜERRORのラベルはダメなんでしょうか?

581:蟻人間
19/10/23 22:22:13.25 bxABcYeD.net
>>575
<wingdi.h>に#define ERROR 0がある。

582:デフォルトの名無しさん
19/10/23 22:22:30.17 R0F6kh0V.net
#undef ERROR

583:デフォルトの名無しさん
19/10/23 22:24:20.08 H9cLmi0l.net
単語1つのラベルなんか使うなってこった

584:デフォルトの名無しさん
19/10/23 22:28:23.69 R0F6kh0V.net
いやC++ではマクロが悪だ

585:575
19/10/23 22:32:44.87 B7dtMHRy.net
ERRORのdefineがあるんですね・・・!
ありがとうございました!

586:デフォルトの名無しさん
19/10/24 09:12:01.73 m57JSwXI.net
クソみたいなマクロにsmallもある
他にもwindows.hには地雷が入念に仕込まれてる
普通の神経の人間が爆死して厭らしい人間だけが生き残るように整えられている厭らしい環境がwindows.hだよ
マトモな人間にはまず耐えられない
頭のオカシイ厭らしい人間だけが残るように設計されているのがwindows.h
このヘッダは頭がおかしい

587:デフォルトの名無しさん
19/10/24 13:45:08.38 VURCQr2T.net
>>581
お前の頭がおかしいだけだと思う

588:デフォルトの名無しさん
19/10/24 13:57:45.03 SfEmAS3k.net
林檎だってcheckマクロでBoostに大迷惑かけてるしお互い様

589:デフォルトの名無しさん
19/10/24 17:59:23.36 0EVcBOG9.net
>>582
そこは
ヘッダだけにな
と言ってやるところだろ

590:デフォルトの名無しさん
19/10/24 18:05:45.17 pgieaG2c.net
ヘッダ「嫌ならincludeするな」

591:デフォルトの名無しさん
19/10/24 19:57:40.06 WiWlXxwu.net
このスレはみんなWindows嫌いなのかな

592:デフォルトの名無しさん
19/10/24 20:17:56.94 TRYJth0S.net
んなわけない

593:デフォルトの名無しさん
19/10/24 21:28:21.53 hxYU3Lux.net
たしかmaxとかもマクロ定義されてたよね
初心者のころはどハマリして殺意がわいたわ

594:デフォルトの名無しさん
19/10/24 21:49:18.24 omM/Gkq5.net
いまはIDEが色変えてくれるからすぐわかるから別にいいけどね

595:デフォルトの名無しさん
19/10/24 23:20:19.58 M5uvwdA8.net
マクロがあればなんでもできる

596:デフォルトの名無しさん
19/10/24 23:40:29.47 PIyGP0m1.net
最近ちょいちょい思うことだが、ある言語のここがどうであーだこうだと議論する場合
テキストエディタでコーディング作業してる連中と IDE でコーディング作業してる連中では
わりと大きな認識の違いがあることが多い

597:デフォルトの名無しさん
19/10/24 23:44:34.75 8Fri6DgZ.net
windows.hのマクロ回りでトラブル起こしているのは、殆んどvisual studio使用者だと思うのだが

598:デフォルトの名無しさん
19/10/25 00:24:04.41 AZBzSxe6.net
認識の違いはコンパイラによるものであってコードエディタは関係ない。

599:デフォルトの名無しさん
19/10/25 00:39:26.61 ghRRxqDU.net
モジュールでマクロとか気にしなくて良くなる(なるといいなぁ...)

600:デフォルトの名無しさん
19/10/25 07:52:28.01 51G3P59H.net
コンパイラ変えてもマクロは変わらんでしょ
せいぜいエラーメッセージ変わるぐらいじゃ

601:デフォルトの名無しさん
19/10/25 09:14:30.39 AZBzSxe6.net
>>595
何言ってるのか意味がわかりにくいエラーメッセージを吐くのはコンパイラでしょ。

602:デフォルトの名無しさん
19/10/25 12:19:38.16 51G3P59H.net
マクロは影響範囲わからんからなんとも
vcでマクロがテンプレートに影響したらマジでわからん
clangはテンプレートのエラーメッセージわかりやすいとかみたな

603:デフォルトの名無しさん
19/10/25 12:45:17.61 yKAgzXLG.net
>>593
お前はまず日本語を正しく認識できるようになれよ…
>>591は連中(=人間)の認識の話な

604:デフォルトの名無しさん
19/10/25 17:33:51.00 AZBzSxe6.net
初心者であればあるほど親切なエラーメッセージが必要なのだけど、VCのエラーメッセージはgccに比べて不親切な印象がある。
STL関連のエラーメッセージは、わかりにくい代表格。かたやgccはprintf系の書式ミスを指摘してくれるなど初心者に優しい。

605:デフォルトの名無しさん
19/10/25 18:03:22.82 AZBzSxe6.net
C#が使いやすいと思っている人は、Visual Studioの入力補完に救われていることに気づいていない。
Visual Studioがなければヘッダーファイル相当のgrep検索もままならない不便な言語であると感じるだろう。

606:デフォルトの名無しさん
19/10/25 18:50:41.74 StYWqeWG.net
VS込みでいいじゃん
どうせC#なんて大半がWindows向けなんだしVS使える環境で開発してるでしょ
って変なこと言うと思ったらADSLか

607:デフォルトの名無しさん
19/10/25 19:00:26.80 r/2esNbS.net
referencesource.microsoft.comみたいなありがたいものがあるのに

608:デフォルトの名無しさん
19/10/25 19:58:41.60 q2iK2L4t.net
基本的には MSDN こそ C++ である。

609:デフォルトの名無しさん
19/10/26 00:56:44.62 7AoWPXY8.net
class A{};
namespace N
{
class B{
friend class A;
int i;
};
class A{
A(){b.i = 0;}
B b;
};
};
これをコンパイルできるようにするにはどうすればいいですか?
・クラスAを名前空間Nの下に書く
・名前空間NのクラスAを別の名前にする
・最初のクラスAを別の名前にする
これ以外でできますか?

610:デフォルトの名無しさん
19/10/26 00:59:53.57 SyjizfQh.net
全部消す

611:デフォルトの名無しさん
19/10/26 01:35:09.91 dcsgYCXg.net
>>604
「コンパイルできるようにする」
というだけであれば、何も修正しない元のままでもコンパイルできるはずだし、
最初の class A {} の行をコメントアウトする、消す。
Nの中のAを消す、namespace N {・・・} の部分を全部消す、
などなどいくらでも有りえる。

612:デフォルトの名無しさん
19/10/26 06:20:26 3CUGZWDU.net
BのfriendをN::AにしたいってことであればNとBの間にclass A;とAの宣言を入れる
これ以上のエスパーは無理

613:デフォルトの名無しさん
19/10/26 08:16:08.08 kGqH5EJJ.net
>>604
g++だと、現状のままでok
vs2019は、friend宣言の対象が::AになっていてC2248
::Aをコメントアウトするとok
正しいのはg++
N4713 6.4.1. Unqualified name lookup (7.4)
Note: When looking for a prior declaration of a class or function
introduced by a friend declaration, scopes outside of the innermost
enclosing namespace scope are not considered; see 10.3.1.2.

614:デフォルトの名無しさん
19/10/26 21:50:06.24 JNlbd3QN.net
投稿テスト
N3337 3.4.1 Unqualified name lookup
Note: When looking for a prior declaration of a class or function
introduced by a friend declaration, scopes outside of the innermost
enclosing namespace scope are not considered; see 7.3.1.2.

615:デフォルトの名無しさん
19/10/26 22:03:59.61 JNlbd3QN.net
vs2019で::Aをコメントアウトするとokの意味がわからんorz

616:デフォルトの名無しさん
19/10/27 08:17:56.25 /F19lavA.net
試してないが、理論上はこれでいけるはず :
namespace N
{
class A;
class B{
int i;
friend class A;
};
class A{
B b;
A(){b.i = 0;}
};
};

617:デフォルトの名無しさん
19/10/27 08:27:09.91 C3DsRDjK.net
N::Aを前方宣言するなら、宣言を名前空間Nの中に入れるかN::Aで宣言する必要があるってのはC++の規約通りじゃないのか?
>>608が意味わからん

618:デフォルトの名無しさん
19/10/27 09:08:16.09 M7FyKfzv.net
friend宣言は、当該宣言を含むクラスが属するスコープを対象とし
なおかつ、対象スコープに識別子を導入しない
class G
{
friend class A; //::A
};
namespace H
{
class I
{
friend class A; //H::A
};
}

619:デフォルトの名無しさん
19/10/27 12:21:23.69 C3DsRDjK.net
>>604はfriend宣言ではなく前方宣言の問題なんだが?

620:デフォルトの名無しさん
19/10/27 14:03:45.40 M7FyKfzv.net
いや前方宣言は関係ない
「もし」::Aがあったら、H::Aがあったら
と言っているだけのものだ

621:デフォルトの名無しさん
19/10/27 14:25:39.88 vcUKQgsd.net
>>614
前方参照をfriendがどう解釈するかの問題だろ

622:デフォルトの名無しさん
19/10/27 15:28:12.27 itfBjV2c.net
>>616なのは明白だが
>>604のコードのどこにコメントアウトすべき::Aがあるのかわからん…
ひょっとして、>>604が禁じていないのを良いことに、
最も外側のclass A{};を丸ごとコメントアウトしようとしている?

623:デフォルトの名無しさん
19/10/27 15:53:16.22 ho9vIROt.net
>>617
???
>>608はVisual Studio 2019(2017でも同じだったが)の話だと言うことは理解できてるか?

624:デフォルトの名無しさん
19/10/27 15:56:22.52 M7FyKfzv.net
>>617
そのとおりだが?
//class A{};
namespace N
{
class B{
friend class A;
int i;
};
class A{
A(){b.i = 0;}
B b;
};
};
friend宣言が識別子を導入したり
関係ないはずのグローバルに干渉するなど
vcはfriendにクセがある

625:デフォルトの名無しさん
19/10/27 16:07:13.81 6193c9It.net
規格的にはどうなるのが正しいの?
むしろ、もとの話がどうしたいのかに依る気がしないでもない

626:デフォルトの名無しさん
19/10/27 16:13:20.11 rrcAfXPk.net
>>620
規格の話は>>608じゃねーの?
コンパイルできるようにするにはg++にするかVisual Studioなら>>619みたいにするってことでしょ
それ以外なら環境を提示してねってことかと

627:デフォルトの名無しさん
19/10/27 16:22:22.30 itfBjV2c.net
>Visual Studioなら>>619みたいにするってことでしょ
URLリンク(festy.jp)
>>604
>・最初のクラスAを別の名前にする
と何が違うんだそれ

628:デフォルトの名無しさん
19/10/27 16:55:17.47 rrcAfXPk.net
>>622
一緒だよ
だからそれができないならg++(とか他のちゃんと規格準拠して処理系)にしろって書いてあるだ
まあVisual Studioが規格準拠するのを待つとかMSにねじ込むか金払って対応してもらうとかでもいいけどw

629:デフォルトの名無しさん
19/10/27 20:50:09.77 5FCyBaq0.net
トンチンカンな質問かもしれませんが許して。
<Base>のコンテナを巡回しながら
Base派生の多態性を引数で実現、みたいなことがやりたいのです。
URLリンク(ideone.com)
これのManager::update()が、このままだと当然
func(shared_ptr<Base>,shared_ptr<Base>)を呼ぼうとしてしまう訳ですが
宣言してあるfunc(A,A)とかfunc(A,B)とかfunc(B,B)とかが
呼ばれるようにするにはどうしたらいいですかね?
あるいは、ガラっとコード変わってもだいたい似たようなことを実現するとしたら
どう書きますか?

630:デフォルトの名無しさん
19/10/27 20:52:12.38 oi2VB0wA.net
シェアポの配列を作って添え字で切り替え。

631:デフォルトの名無しさん
19/10/27 20:54:15.22 oi2VB0wA.net
あ、すまん。誤読していた。
>>宣言してあるfunc(A,A)とかfunc(A,B)とかfunc(B,B)とか
多態やってる意味を潰しに来てないか?

632:蟻人間
19/10/27 20:54:19.69 irXhIBVc.net
>>624
funcを仮想化すれば?

633:蟻人間
19/10/27 20:59:49.33 cNZwDfUU.net
もしくはfuncでは仮想化された関数しか使わないとか。

634:デフォルトの名無しさん
19/10/27 21:09:28.45 aWGByvYb.net
>>624
visitorパターン

635:642
19/10/27 21:09:54.33 5FCyBaq0.net
>>627
func(Base,Base)だけをvirtualってこと…ですよね?
え、こういうときにもvirtualて使えるの?と思って試したけどダメですね。
>>628
もうちょっと考えてみますけどたぶん難しいです

636:624
19/10/27 21:14:40.36 5FCyBaq0.net
名前欄間違えてた…
>>629
あー…それかも
なんとなく知ってるだけで
まだ実装したことはないですが
それ正解かもしれません
調べつつやってみます

637:デフォルトの名無しさん
19/10/27 21:34:36.36 4WtkkchW.net
>>624
愚直に dynamic_cast で N*N 分岐からはじめたら?

638:デフォルトの名無しさん
19/10/27 22:12:39.30 5au4GxkL.net
2引数ならdouble dispatchとか

639:デフォルトの名無しさん
19/10/27 22:14:23.71 SYtHJPpD.net
派生クラスの種類が決まっているなら
variantに置き換えたらvisit使えるから簡単

640:デフォルトの名無しさん
19/10/28 05:15:43.29 VJWcm+Z+.net
>>624
こうゆうことやのうて?
URLリンク(ideone.com)

641:デフォルトの名無しさん
19/10/29 01:15:36.46 Vnr+WSpj.net
C++でCOM扱うの苦痛すぎる
何が正攻法なのかさっぱりわからん

642:蟻人間
19/10/29 01:32:18.86 CdNgVa0z.net
>>636
ATL
CComPtr

643:デフォルトの名無しさん
19/10/29 01:41:40.05 Vnr+WSpj.net
別にCOMは作るんじゃないんだよ。
参照するだけなんだよ。
それでもATLなんーーーーーーーーー?

644:デフォルトの名無しさん
19/10/29 01:43:16.61 Vnr+WSpj.net
そもそも文字コードどうなってるんやーーーー
コマンドプロンプトに出す時、どうするんやーー
現在のchcpの設定に従って変換線といかんのカーーーーーー

645:蟻人間
19/10/29 02:28:13.51 OOQqvLIR.net
変換なんてWideCharToMultiByte使って一つ変換関数作ってその関数を使い回せばいいやん。

646:デフォルトの名無しさん
19/10/29 02:42:32.11 /DWax9vx.net
WriteConsoleW

647:デフォルトの名無しさん
19/10/29 04:01:15.69 ymnLB/52.net
>>640
Unicode文字列(絵文字とか)が文字化けするんだよー!
フォントの問題でないことは確認済み

648:デフォルトの名無しさん
19/10/29 04:07:41.50 ymnLB/52.net
例えばググって見つけた、こことか
URLリンク(www.t-net.ne.jp)
wchar_t を const wchar_t にするのはまあいいとして、
日本語はOKだけど絵文字とか化けるじゃねーか
わーけわかねなんdfっrね;jk

649:デフォルトの名無しさん
19/10/29 04:13:15.89 ymnLB/52.net
ん?WideCharToMultiByteってShiftJISに戻すやつじゃねーのか?
俺はUnicode文字すべてを表示したいだけだぞ

650:デフォルトの名無しさん
19/10/29 04:20:56.50 xS90z6YC.net
chcpくらい使えよ

651:デフォルトの名無しさん
19/10/29 04:26:03.90 /DWax9vx.net
windowsのコマンドプロンプトはまだ絵文字とかに対応してないよ

652:デフォルトの名無しさん
19/10/29 04:29:31.79 YQKoC2Uo.net
>>646
全てではないだろうけど対応してる。

↑文字化けしそうだけど、横向きのハートとか
❤ とか

653:デフォルトの名無しさん
19/10/29 04:29:44.12 YQKoC2Uo.net
お、文字化けしなかったw

654:デフォルトの名無しさん
19/10/29 04:30:10.10 YQKoC2Uo.net
?????
Jane経由だとだめだろうな

655:デフォルトの名無しさん
19/10/29 04:31:42.98 YQKoC2Uo.net
>>645
chcp 65001にしてもムダだったぞ

656:デフォルトの名無しさん
19/10/29 04:54:41.95 pnjVF+Pb.net
コマンドプロンプトよりJaneは早く絵文字に対応しろ

657:デフォルトの名無しさん
19/10/29 05:06:04.44 xS90z6YC.net
>>650
それutf8じゃねーか

658:デフォルトの名無しさん
19/10/29 05:14:54.35 YQKoC2Uo.net
>>652
ぐぐってからいえwww

659:デフォルトの名無しさん
19/10/29 05:19:50.17 YQKoC2Uo.net
なんでコードページ932なのに、NSimSunにすると
日本語以外もちゃんと表示できるのかわからない

660:デフォルトの名無しさん
19/10/29 05:26:40.69 xS90z6YC.net
wcharがutf8なのか?あほか?

661:デフォルトの名無しさん
19/10/29 05:36:55.26 YQKoC2Uo.net
Visual StudioのソースコードのデフォルトはBOM付きUTF8なんだな

662:デフォルトの名無しさん
19/10/29 06:38:53.94 d5obkYRE.net
Windows依存の話は、以下すれでどうぞ。
Win32API質問箱 Build125
スレリンク(tech板)

663:デフォルトの名無しさん
19/10/29 12:08:17.89 HlsBbRfa.net
自分の理解と違ってたので教えてください。
class hoge{
hoge(){}
hoge(const hoge& h){}
~hoge(){}
}
hoge func(){
hoge h;
return h;
}
main(){
hoge h = func();
}

この時、引数なしコンストラクタとコピーコンストラクタ、デストラクタが2回呼ばれると理解してたんだけど、実際動かすとコンストラクタとデストラクタが1回づつしか呼ばれない。
理由ってなんですか?
ちなみにgccで、c++03、c++11でも同様の結果でした。

664:はちみつ餃子
19/10/29 12:09:55.91 0JV7MfqT.net
>>658
RVO でググって

665:デフォルトの名無しさん
19/10/29 12:10:21.23 gvGgQxyJ.net
最適化で消された

666:デフォルトの名無しさん
19/10/29 12:14:30.49 HlsBbRfa.net
>>659
まさにピンポイントでした。
ありがとうございます。

667:デフォルトの名無しさん
19/10/29 13:58:53.43 cpD/FVFn.net
>>636
node.js

668:はちみつ餃子
19/10/29 13:59:57.20 0JV7MfqT.net
>>636
マイクロソフトのコンパイラならまあまあ補助があったりするでしょ。
それでも面倒くさいことにかわりないけど。

669:デフォルトの名無しさん
19/10/29 15:55:18.54 VnX4qZP9.net
失礼します。テストです:
ハート:❤
横向きハート:❥

670:はちみつ餃子
19/10/29 16:08:16.15 0JV7MfqT.net
>>664
失礼な奴だな!

671:デフォルトの名無しさん
19/10/29 18:43:54.18 NclFvQSb.net
>>663
補助なんてあったっけ?
まあ俺の知識はもう5年以上前の知識だから最近はちょっとはマシになったのかな

672:デフォルトの名無しさん
19/10/29 21:55:11.67 daQRKG1l.net
typedef const struct {
int i;
int j;
} X;
X arr[2] = {
{1,3},
{2,4}
};
int main() {
X *ptr = arr;
printf("%d %d %d <- always zero", ptr->i, (ptr+1)->i, (ptr-1)->i);
return 0;
}
グローバル const struct の配列のアドレスを上に行ったら、常に0が入ってるんだけど、
これは、どのハードウェアでもこうなると仕様と決まってるの?

673:デフォルトの名無しさん
19/10/29 22:07:48.92 VnX4qZP9.net
>>667
決まってない。
範囲外のアクセスなので、本来は絶対にやってはいけない。
読むだけでも不法例外が起きてしまう可能性もあるが、
書くのはもっとダメ。
たまたま、コンパイラシステムが何らかの目的で使っている
グローバル変数が arr 配列の直前にい配置されていて、
それが0になっているか、padding領域がたまたまそこにある
だけだと考えられる。

674:デフォルトの名無しさん
19/10/29 23:33:23.00 B0gwdLKJ.net
.bssは0初期化されてる

675:デフォルトの名無しさん
19/10/30 04:47:43 oMdYt0Tq.net
オブジェクトがスタックに作られてるかヒープに作られてるかってどうやって調べるの

具体的にはboostのmulti_arrayがどっちに作られてるか知りたい

676:デフォルトの名無しさん
19/10/30 06:54:34.02 2wpdugOW.net
>>668
そりゃそうか。0で埋まってりゃコードが少し短くなって助かるんだが、まあやめとこう。

677:デフォルトの名無しさん
19/10/30 07:31:59.85 yREk150+.net
>>670
アドレスでわかる
正しくはリンカからロケーションを取得だが
簡易的には自動変数のアドレスと上の方の桁が同じかどうかでも見当はつく

678:デフォルトの名無しさん
19/10/30 09:19:14.69 C/RG5q83.net
>>670
アドレスでも分かるが、それはスタック領域のアドレス範囲をマップファイル
やEXEヘッダなどから読み解かないといけないので、boostのソースを読むのが
一番楽。
もう一つは、
1. auto local変数でint a; printf( "%08X", &a );としたもの
2. global 変数で、int g_b; printf( "%08X", &g_b );としたもの
3.ヒープの先頭アドレスを調べるため、int *p_c = new int[16];
 printf( "%08X", p_c );としたもの
で表示されたアドレスと boost の multi_arrayのアドレスとを比較して、
上位アドレスが近いかどうかで判別できる。1,2,3のそれぞれはまとまった
領域のアドレスを使っているので、推定ではなく断定できる。

679:デフォルトの名無しさん
19/10/30 09:33:17.69 scNMtFri.net
どう考えてもヒープだろ

680:デフォルトの名無しさん
19/10/30 09:45:24.54 vMK+Q7lg.net
>>670
ローカルスコープだけがスタック。
newしたものはヒープ。

681:デフォルトの名無しさん
19/10/30 11:38:54.67 M6J6raPE.net
コンテナの場合はスタックに置いたつもりでも、コンテナがデータ部分を内部でnewするとかそういう話だろ

682:はちみつ餃子
19/10/30 12:07:14.45 qu4eF7c5.net
>>667-668
仕様上は配列の範囲外を指すポインタを作るのさえも未定義。
たとえアクセスしなくても。
なので、 ptr-1 という式の時点で未定義動作になる。
ただし、アクセスしないなら配列の最後の要素より一個うしろを指すポインタを作るのは許される。
つまりこの例で言えば ptr+2 や &ptr[2] は有りだけど ptr[2] は駄目。
&ptr[2] は ptr[2] に対して & を付けているので一見すると途中で ptr[2] を評価しているように見えるけど、
・ ptr[2] は (*(ptr+2)) の構文糖である
・ * の結果に & を適用している場合には * も & も評価されず、両方とも取り除いたのと同じことになる
というルールの合わせ技によって &ptr[2] は ptr+2 と同じ意味になる。
ちなみに、配列ではないオブジェクトは要素が一個の配列と同じレイアウトを持つことは保証される。

683:デフォルトの名無しさん
19/10/30 12:14:10.66 pPHw66rS.net
>>677
&*p を p とみなす特別ルールは C の規格にあるけど C++ には無かったりする。
もう10年以上審議中。 URLリンク(wg21.cmeerw.net)

684:デフォルトの名無しさん
19/10/30 12:21:16.92 C/RG5q83.net
>>677
>ちなみに、配列ではないオブジェクトは要素が一個の配列と同じレイアウトを持つこと>は保証される。
しかも、TYPE arr[N] の場合、それぞれの要素間隔であるところの
&arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
struct TXxx { BYTE a[3] }; のように中途半端な内容を持っている場合、
標準的には、sizeof(TXxx)は最後のpaddingまで含めた4になる。
その結果、古くからCの仕様書に載っている通り、
 &arr[k] = (TYPE *)(((BYTE *)arr) + sizeof(TYPE) * k)
の式が常に厳密に成り立つことが保証される。

685:デフォルトの名無しさん
19/10/30 12:25:41.94 C/RG5q83.net
>>678
operator&(), operator*() をユーザーが定義した場合には、それに従うが、
定義しなかった場合、&*pX == pX が どんなポインタ pX についても
成り立つことは保証されるはず。

686:デフォルトの名無しさん
19/10/30 13:28:14.72 JDSjHFuf.net
>>670
一般的なPC環境なら、
適当に用意した別の関数を呼び出して(multi_arrayのインスタンスがまだ有効で、インスタンス生成したスレッドと同一スレッドからなら、どこから呼び出してもよい)、
その関数のローカル変数のアドレスよりも&multi_array[0]の値のほうが大きければ、multi_arrayのデータ領域はスタックに確保されたと判断できるのでは

687:デフォルトの名無しさん
19/10/30 13:38:23.28 C/RG5q83.net
>>681
自分も最初、同じような勘違いをしていたが、
シングルスレッドの場合に限定すれば、
スタックの構造からすれば、最初に確保したローカル変数のアドレスが、
そのごろのローカル変数のアドレスよりも必ず大きい。
そして、ヒープから確保したオブジェクトのアドレスは、必ずそれらよりも大きい。
なので、後から別の関数を呼び出す必要はない。
main()関数の中で最初に定義したローカル変数のアドレスが分かればそれで十分。

688:デフォルトの名無しさん
19/10/30 13:39:27.23 C/RG5q83.net
>>682
誤:そのごろのローカル変数のアドレスよりも必ず大きい。
正:その後のローカル変数のアドレスよりも必ず大きい。
早い話が、スタックは、上下逆になっていることが味噌。

689:デフォルトの名無しさん
19/10/30 16:43:27.90 iACLsVPd.net
0 埋め勝手に期待してると
Debug build と Release build の変化ではまるんじゃね

690:デフォルトの名無しさん
19/10/30 18:21:24.13 sLIKMMS8.net
未定義動作に頼って幸せになった人間はいない

691:デフォルトの名無しさん
19/10/30 18:25:45.90 PFJwOjFS.net
問題は未定義動作が多すぎることだ

692:デフォルトの名無しさん
19/10/30 19:14:52.52 NnKRxbK9.net
>>682
> そして、ヒープから確保したオブジェクトのアドレスは、必ずそれらよりも大きい。
スタックエリアとヒープエリアの前後関係なんて決まってたっけ?

693:デフォルトの名無しさん
19/10/30 19:53:22.92 /8g3afGg.net
c++なら暗黙に0で初期化するところでcだと死ぬ

694:はちみつ餃子
19/10/30 20:10:37.29 qu4eF7c5.net
Boehm GC にスタック・ヒープの範囲を判定する部分があったはず。

695:デフォルトの名無しさん
19/10/30 20:42:33.17 MNbPntdA.net
>>682
ヒープから確保したアドレスがスタックより大きいっていうのはかなり特殊な環境では?

696:デフォルトの名無しさん
19/10/30 20:46:40.08 7FaQcqiv.net
>>682
スタックとヒープのアドレスに前後関係の縛りなんかねえよ
互いに全く別個のデータ構造で相互に依存関係はない

697:デフォルトの名無しさん
19/10/30 21:02:17.94 xN/ut28D.net
お前ら甘いぞ
ヒープから確保したメモリをスタックにすることもできるんやで
逆にいうとスタックの情報もとれる
pthread_attr_getstackな

698:デフォルトの名無しさん
19/10/30 21:28:56.04 KWwo/1iW.net
URLリンク(ideone.com)
デストラクタを後から書き換えるってできなかったっけ?

699:デフォルトの名無しさん
19/10/30 21:37:47.50 scNMtFri.net
なんで出来ると思ったのか

700:デフォルトの名無しさん
19/10/30 21:41:50.59 /8g3afGg.net
おまえらはなんですぐ破壊的なメモリアクセスしようとするんだよ。

701:デフォルトの名無しさん
19/10/30 21:44:55.49 KWwo/1iW.net
>>694
なんでだろ・・・。
できなそうだな。さんきゅー。

702:デフォルトの名無しさん
19/10/30 21:47:25.90 M6J6raPE.net
変にトリッキーなことをせず普通に書けば平和なのに

703:デフォルトの名無しさん
19/10/30 21:51:21.63 Z1e8Gfkt.net
平和を求めるならc++使わないことだな

704:デフォルトの名無しさん
19/10/30 21:56:38.45 Z1e8Gfkt.net
>>696
virtualでないと子のデストラクタは呼ばれないってのとごっちゃになってるとか?

705:デフォルトの名無しさん
19/10/30 21:57:32.16 /8g3afGg.net
>>698
平和は求めるが性能も求めるから仕方なく使うのがc++だよ、馬鹿。

706:デフォルトの名無しさん
19/10/30 22:07:52.76 KWwo/1iW.net
>>699
多分それだ。もやもや取れたわ。ありがとう。

707:デフォルトの名無しさん
19/10/30 22:15:48.21 Z1e8Gfkt.net
>>700
お前moveだからコピーコストゼロ!カロリーゼロとか言ってるだろ

708:デフォルトの名無しさん
19/10/30 22:18:45.46 T2yRPHdv.net
>>693
正直何をしたいのかさっぱりわからん

709:デフォルトの名無しさん
19/10/31 00:30:04 Mfb82uAb.net
>>687
なるほど、想定していたのは、Windows環境限定だった。

710:デフォルトの名無しさん
19/10/31 01:11:19 Z73hoFPo.net
>>679
> &arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
いや、 &arr[k + 1] - &arr[k] は 1 でしょ。

> その結果、古くからCの仕様書に載っている通り、
>  &arr[k] = (TYPE *)(((BYTE *)arr) + sizeof(TYPE) * k)
> の式が常に厳密に成り立つことが保証される。
少なくとも C++ の規格にもそんな保証は載ってないよ。
逆に、 TYPE が BYTE と一致するような場合を除いて、動作は未定義になると明記されてる。
URLリンク(timsong-cpp.github.io)

たぶん C の規格にも無かったと思うんだけど、「Cの仕様書」って何のこと言ってるの?

>>680 も、規格で保証されると言ってるなら誤り。
特定の実装(特に C もサポートしてる実装)では保証されているとか、
保証されてないと困るという話ならそうなんだろうとは思うけど。

711:デフォルトの名無しさん
19/10/31 07:54:20 CWgnmwch.net
保証は知らんけどアドレス計算だから1じゃなくてsizeofの値じゃないのそれ
あとだめならベクタで&v[x]みたいのも未定義になっちゃうけども

712:はちみつ餃子
19/10/31 12:29:41.78 /W+zTx1p.net
>>705
俺も仕様としての保証はないと思う。
C の規格を見て関連しそうな項目として
- ポインタを型変換して変換後のアライン (処理系定義) が正しければそれを元の型に再変換したものは変換前と等しい
- ポインタを別のポインタに型変換した後のアラインが正しくなければ未定義
- ポインタを文字を指すポインタに型変換した場合、オブジェクトの最も低位のアドレスを指す
- 文字を指すポインタに変換されたポインタは元のオブジェクトの大きさまで連続して増分すると
  そのオブジェクトの残りのバイトへのポインタを順次生成できる
(注:ここで言うポインタには関数ポインタを含まない)
という保証は見つけられたので
(((BYTE *)arr) + sizeof(TYPE) * k)
までは妥当な式と言えると思うんだけど、 (TYPE *) というキャストが出来る根拠は見つけられなかった。

713:デフォルトの名無しさん
19/10/31 13:00:56.65 Mfb82uAb.net
>>707
C言語の基礎として、TYPE *ptr に対し、
 ptr + k == (TYPE *)(((BYTE *)ptr) + sizeof(TYPE) * k)
は保証されているはず。

714:デフォルトの名無しさん
19/10/31 13:06:36.29 iFqs222y.net
×基礎
○妄想の中の理想世界・ご都合ワールド

715:デフォルトの名無しさん
19/10/31 13:21:36.49 Mfb82uAb.net
URLリンク(en.cppreference.com)
1. sizeof( type ) Returns the size, in bytes, of the object representation of type
2. When applied to an operand that has structure or union type,
the result is the total number of bytes in such an object, including
internal and trailing padding. The trailing padding is such that
if the object were an element of an array, the alignment requirement
of the next element of this array would be satisfied, in other words,
sizeof(T) returns the size of an element of a T[] array.
3. Number of elements in any array a including VLA (since C99) may be
determined with the expression sizeof a / sizeof a[0]. Note that
if a has pointer type (such as after array-to-pointer conversion of
function parameter type adjustment), this expression would simply
divide the number of bytes in a pointer type by the number of bytes
in the pointed type.
URLリンク(en.cppreference.com)
10. If the pointer P points at an element of an array with index I, then
11. P+N and N+P are pointers that point at an element of the same array with index I+N.
12. P-N is a pointer that points at an element of the same array with index {tt|I-N}}.
20. If the pointer P1 points at an element of an array with index I (or one past the end)
and P2 points at an element of the same array with index J (or one past the end), then
P1-P2 has the value equal to J-I and the type ptrdiff_t (which is a signed integer type,
typically half as large as the size of the largest object that can be declared)

716:デフォルトの名無しさん
19/10/31 13:43:36.78 hGg8JwcT.net
C++のヘッダファイルのクラス定義って、
privateまで定義しないといかんのが嫌だな。
privateだから内部に隠蔽されて、外部からは知らなくていい情報なのに
内部で使ってる型をヘッダファイルに書かなければいけないから、
それをincludeしてる方も、その型の存在を知ってしまう。
どうにかならんのかな?

717:デフォルトの名無しさん
19/10/31 13:54:48.05 Nmr38VJU.net
ヘッダに描くのをやめればいい

718:デフォルトの名無しさん
19/10/31 14:01:21.28 Mfb82uAb.net
>>710
「1.」によれば、sizeof(x)は、xのバイトサイズである。
「2.] によれば、xが構造体の場合、sizeof(x)には、構造体のメンバの間や
最後のpaddingのサイズまで含まれている。
「3.」によれば、TYPE a[N]; の場合、sizeof(a)/sizeof(a[0]) == N
が保証されている。a[0] の型は TYPE なので、これは、
sizeof(a)/sizeof(TYPE) == N
であることを示す。sizeof(a)とは、配列型a全体のサイズであるので、
これはつまり、a[k] のアドレスが、(a[0] のアドレス) + sizeof(TYPE) * k
であることを意味している。
よって、>>708 は正しい。

719:デフォルトの名無しさん
19/10/31 14:04:09.17 /uM4xbrd.net
>>711
pimpl

720:デフォルトの名無しさん
19/10/31 14:46:45.02 Mfb82uAb.net
>>705
>> &arr[k] と &arr[k + 1] の差は、厳密に sizeof(TYPE)に一致する。
>いや、 &arr[k + 1] - &arr[k] は 1 でしょ。
この場合の「差」とは、減算演算子 x - y の結果のことではなく、
アドレスの差のことです。丁寧に書けば、
「&arr[k] のアドレス値と &arr[k + 1] のアドレス値の差は、厳密に sizeof(TYPE)
 に一致する。」または、
「arr[k] のアドレスと arr[k + 1] のアドレスの差は、厳密に sizeof(TYPE)
 に一致する。」
となります。

721:デフォルトの名無しさん
19/10/31 14:50:36.73 Mfb82uAb.net
>>691
言語仕様的には決まっていませんが、Win32で実験する場合、
最初の質問者が、答えを見つける手段としては、正しいやり方なのです。
Win32で実験してヒープからの確保なのかどうか判明してしまえば、同じ
boostのソースを他の環境で動かしても、#ifdef などで動作が変えられていない
限りは、同じ結果となるからです。

722:はちみつ餃子
19/10/31 14:53:56.72 /W+zTx1p.net
>>713
アドレスがどうこうじゃなくてキャストが許されるかっていう話なんだけど。

723:デフォルトの名無しさん
19/10/31 15:27:23.28 CWgnmwch.net
ポインタのキャストてポインタが指してるアドレスのデータの解釈だけの問題だから許されないキャストがそもそもないのでは
適切かどうかは知ったことではないが
というか配列のデータが連続していれば当然のごとく成り立つ話じゃん
それは保証されてるわけだし

724:デフォルトの名無しさん
19/10/31 16:06:33.06 hGg8JwcT.net
>>714
サンクス。集約を使えば行けるんかいなーとか雑に思っていたが、
そういうイディオムがあるんだな!

725:デフォルトの名無しさん
19/10/31 16:29:14.27 Mfb82uAb.net
>>718
構造体型へのポインタ同士については、単なる解釈し直しではなく、
アドレスの加減算を伴うことがあります。
しかし、BYTE型へのポインタから構造体型へのポインタへのキャストに
ついては、解釈のし直ししか、コンパイルのしようがなく、その場合に
ついては、ポインタの指すオブジェクトがマシン後レベルで同じアドレス
を持つことになります。ただし、厳密な仕様は知りません。

726:はちみつ餃子
19/10/31 16:32:02.98 /W+zTx1p.net
pimpl ってプライベートなメンバを隠したいだけのために導入するのは面倒くさ過ぎない?
手間かけてでもやりたいって場面もあるのかもしれんが、どうにも割に合う気がしない。

727:デフォルトの名無しさん
19/10/31 17:07:47.69 NdDnFbFX.net
どうしても実装を隠さないと発狂する人が使う

728:デフォルトの名無しさん
19/10/31 17:11:39.47 M7zdaumA.net
unique_ptrで作ればそれだけで勝手にmovableなクラスになって便利だよpimpl

729:デフォルトの名無しさん
19/10/31 17:17:39.90 hGg8JwcT.net
>>721
プライベートなメンバを隠すと言うよりも
依存関係を断ち切らせたかった。
hoge.h と hoge.cpp があって、
hoge.cpp から #include<hoge.h> してる
main.cpp があってHogeクラスを使うから、#include<hoge.h> してる。
この時、mainは、Hogeクラスだけを使ってることにしたい。
でも、hoge.cpp は private で Hage func(); メソッドを定義してる。
つまり hoge.cpp は #include<hage.h> をしている。
そうすると,mainは、Hogeクラスだけ使うつもりなのに
間接的に hage.h もインクルードしてしまって、Hageクラスのこと知ってることになる。

Hogeを知るとHageも知ってしまう
Hageを隠したかったんだよ!

言いたかったことはこれ

730:デフォルトの名無しさん
19/10/31 17:29:24.06 Mfb82uAb.net
>>724
また髪の毛の話してる、などというと荒れそうなので決して言いません。

731:はちみつ餃子
19/10/31 17:52:49.82 /W+zTx1p.net
C++20 でモジュールの機能が入るとかいう話になってるから
それが成れば pimpl なんていらんようになると思うんだが、
実際のところモジュールの様子ってどうなの?ちゃんと入りそう?

732:デフォルトの名無しさん
19/10/31 18:23:02.02 ZttcTVl1.net
無理。
テンプレートとの両立、オーバーヘッドの問題
どの視点でみてもくそなものしかできないことは明白。
こういうのに引っかかるバカが増えたよね。

733:デフォルトの名無しさん
19/10/31 18:32:01.00 gpc+5FVL.net
>>721
そう思うのは複数人で規模のでかいもの作ってないから

734:デフォルトの名無しさん
19/10/31 19:37:56.00 /uM4xbrd.net
pimplは開発規模は関係なくて、ライブラリの公開するヘッダでユーザーに関係ないものを隠すために使わないか?

735:はちみつ餃子
19/10/31 20:03:49.64 /W+zTx1p.net
>>729
それも pimpl の目的としてはあるんだけど、 >>724 が書いているように C++ だとファイルの依存関係が必要以上になることもある。
それをどうにかしたら make で差分ビルドしたときに走るタスクが少なくなるので
規模が大きいプログラムで pimpl を使うとビルドがだいぶん速くなるということはありうる。
規模が小さいと体感するほどの差が出ない。 割に合わない。
そういう意味では規模は関係ある。

736:デフォルトの名無しさん
19/10/31 20:09:29.87 jES25g+p.net
個人的には、自分ひとりで作ってるプログラムは、高頻度で全ビルドに
かける癖が付いてしまってる。
こうしておくと、OSをSleepモードにしていて、誤って電源を切ってしまったような
時にIDEが管理しているプロジェクトのデータファイルの何かが壊れていても
気付なかった時や、プロジェクトのバックアップ処理の時のコピー操作の何らか
の間違いで何かがおかしくなってしまったようなときに変な不具合に悩まされなく
て済む。

737:デフォルトの名無しさん
19/10/31 22:29:01.40 GkSnEle2.net
C++とオブジェクト指向をきちんと身につけてる人ばかりの環境ならいいんだけどね、pimpl
経験不足な人だと理解出来なさそう

738:デフォルトの名無しさん
19/10/31 22:54:10.87 /p/NkBNt.net
使ってるうちにインターフェースを使った典型的な奴とそう変わらない事に気付く

739:デフォルトの名無しさん
19/10/31 22:58:21.62 KjvgkRuG.net
継承使いたくないからpimplの方が好き

740:デフォルトの名無しさん
19/10/31 23:14:49.56 FGj4X+XO.net
cpprefjpのサンプルの赤字の部分使い方合ってる?
URLリンク(cpprefjp.github.io)

741:デフォルトの名無しさん
19/10/31 23:43:47.06 /p/NkBNt.net
確かに、select_on_container_copy_construction(other.alloc_)が正しいような気はする

742:デフォルトの名無しさん
19/11/01 00:03:47.15 8rUFWNXZ.net
テンプレート活用のための最適化が全盛期の今 pimpl は時代遅れ。

743:デフォルトの名無しさん
19/11/01 00:09:16.78 rKg4WNgJ.net
はいはい

744:デフォルトの名無しさん
19/11/01 00:19:47.84 TUcr0tQH.net
pimplが時代遅れというのなら、それに代わる
依存する必要がない所を断ち切る方法を提示してくれ

745:デフォルトの名無しさん
19/11/01 00:24:57.04 8rUFWNXZ.net
>>739
クラスの前方宣言。
テンプレートによるコンパイルエラー回避。

746:デフォルトの名無しさん
19/11/01 01:06:00.24 pNQbmHLO.net
>>739
インターフェースと継承

747:デフォルトの名無しさん
19/11/01 03:35:55 TUcr0tQH.net
>>740-741
どちらも型を書くので依存を断ち切れてない

748:デフォルトの名無しさん
19/11/01 05:46:43 xzGeRMKo.net
pimplでも型を書くのに、何を言っているんだか
そんなに型を書くのが嫌なら、Cの不透明型でも使ってろ

749:デフォルトの名無しさん
19/11/01 06:27:26.52 62eq0k7o.net
pimplの目的も方法も全く理解してないって白状したぞこいつ

750:デフォルトの名無しさん
19/11/01 06:54:21 vkO9vKkI.net
>>739
目の前のパソコンを窓から投げ捨てます

751:デフォルトの名無しさん
19/11/01 07:17:25.47 luUnrp0t.net
privateをどうしても隠蔽したいならpimpl使うのもやむを得ないのかも知らんけど、そんな事態になったこと無いからよくわからんな

752:デフォルトの名無しさん
19/11/01 07:43:37.38 62eq0k7o.net
ライブラリ作る時にstd::unordered_mapとかメンバに使いたいと思わないもんなのか、よくわからんな
pimplで.cppに閉じ込めないとコンパイラやSTLのバージョン違いで壊れるんだけど

753:デフォルトの名無しさん
19/11/01 07:44:21.36 nMXewbQV.net
>>739
自部屋に引き籠もって外界との依存を断ち切ります。

754:デフォルトの名無しさん
19/11/01 07:58:26 OvwU0XDV.net
ライセンスに書いとけば良い
・プライベートは見ないで下さい。お触り禁止。

755:デフォルトの名無しさん
19/11/01 08:11:36 s5avmMq4.net
ただ単に仕様と実装をすっきり分離できるというだけでも充分な動機になる

756:デフォルトの名無しさん
19/11/01 08:20:42 luUnrp0t.net
>>747
> pimplで.cppに閉じ込めないとコンパイラやSTLのバージョン違いで壊れるんだけど
ん?どう言うこと?
なんかやり方間違えてね?

757:デフォルトの名無しさん
19/11/01 08:22:07 luUnrp0t.net
>>750
private部分を見なきゃいいだけだろw
そもそも実装は.cppに書くんだし

758:デフォルトの名無しさん
19/11/01 08:25:35 StFJ+6Yp.net
エディタが貧弱だったころの名残を未だに引き摺っている
仕様と実装を分離したらそれだけでファイルが倍に増えて管理が面倒になる
仕様はソースコードから逐次自動生成すればいい
なので昨今の言語はIDEに迎合していて、暗黙の大前提でIDEでの運用が見込まれている
それ単体で成り立つものでは無くなっている

759:デフォルトの名無しさん
19/11/01 09:01:23 DyENPU43.net
因果関係を理解できない人ってプログラマ向いてない

760:デフォルトの名無しさん
19/11/01 09:41:29 Oq+eTBHB.net
class Util() {
public:
  int aaa();
  std::string bbb();
private:
  MinorClass mc;
  MinorClass mc zzz();
}


こういうユーティリティクラスがあって便利だなーって思ったときに、
便利だと思うのはaaaメソッドとかbbbメソッドであって
内部で使ってるMinorClassとかどうでもいいねん

Utilクラスのインクルードファイルはインクルードしたいけど
MinorClassのインクルードファイルはインクルードしたくないねん
そんなもんインクルードしたらMinorClassが変更になっただけで
Utilクラス使ってるところも変更になるやろ?

761:はちみつ餃子
19/11/01 10:06:12.42 ichmHmwx.net
>>755
そこをわからんって言ってるやついないんだよ。
わかった上で変更になったらどんくらい問題なんや? 別にええやろ。 と言う場面の方が多いという話なんだよ。
pimpl が有用な場面があるっていう主張もわかるよ。 わかるけど、そういう場面に遭遇したことないなぁという話なんだよ。

762:デフォルトの名無しさん
19/11/01 10:29:23.31 9RAuu3bH.net
>>755
それだけならMinorClassを前方宣言するだけでincludeいらない

763:デフォルトの名無しさん
19/11/01 10:32:58.37 XsK+HhVl.net
>>757
MinorClassの実体をメンバにするなら前方宣言じゃだめ
ポインタなら前方宣言にできる

764:デフォルトの名無しさん
19/11/01 10:33:41.18 o99mOnqi.net
Utilはあるライブラリの公開クラスです
MinorClassは標準ライブラリのテンプレートクラス(例えばstd::unordered_map<Hoge>)です
Aさんはとあるコンパイラver1.0でコンパイルしたライブラリのバイナリとヘッダーを配布しました(ソースは配ってない)
10年後にBさんがこのライブラリのバイナリを入手して使おうと思いました
その間にコンパイラの標準ライブラリも劇的な進化を遂げ、コンテナの内部構造に大幅な改良を加えて超高速化したと宣伝していました
Bさんはヘッダーをincludeしてコンパイラver8.0でビルドしました
さーて何が起こる?Utilがpimplだとどうなる?よくよく考えよう

765:デフォルトの名無しさん
19/11/01 10:43:47.44 9RAuu3bH.net
>>758
そんなんかすまん
勘違いしてた

766:デフォルトの名無しさん
19/11/01 11:01:10.12 XsK+HhVl.net
privateメンバをポインタ型にする手間や不都合とpImplの手間や管理コストのどっちを取るかだろうな
基本的には継承するクラス以外のincludeは排除できる
ヘッダ内部での外部ライブラリのincludeは可能な限り避けるべき

767:はちみつ餃子
19/11/01 11:10:39.87 ichmHmwx.net
>>760
オブジェクトを生成するには「大きさの情報」が必要だと覚えておくとわかりやすいと思う。
クラスの内容がわからないと大きさが確定しないから生成できないけど、ポインタの大きさはわかる。

768:はちみつ餃子
19/11/01 11:11:24.16 ichmHmwx.net
>>759
そういう状況があることはわかるよ。
でもそんなことしねーよって話なんだってば。

769:デフォルトの名無しさん
19/11/01 13:00:57.84 aQLx28Zt.net
>>763
それお前個人がしたことないって言う経験談?
それとも他の代替手段を取るってこと?
先に言っておくと前者ならすっこんでろ

770:はちみつ餃子
19/11/01 13:23:21.41 ichmHmwx.net
>>764
俺がしたことないという経験談だが、
ここで pimpl が割に合わないと出ている意見は
そういう状況があんまりないという内容だということの説明でもある。
そういう状況で必要だってのはわかってるし、
そういう状況にあるなら使えばいいよ。
それはわかってるんだよ。
だからしつこく説明しないいよっていう話。

771:はちみつ餃子
19/11/01 13:29:29.85 ichmHmwx.net
要するに >>759 はまるで見当はずれのこと言ってんなぁという感想。

772:デフォルトの名無しさん
19/11/01 14:32:22.73 o99mOnqi.net
単機能ライブラリ作って渡す仕事してる人にとっては日常なんで、検討外れとか抜かされても勝手なこと言ってんなあとしか
まあ、OSSしかやらないとか、最終の実行バイナリしか作らないとか、そもそも個人プレーで人にプログラム成果物渡したりしないとかなら、
pimplの価値わからんという気持ちになるのはしょうがないし、それが世界の全てだと思っちゃうのかもな

773:はちみつ餃子
19/11/01 14:59:10.92 ichmHmwx.net
>>767
それが全てといってるわけじゃなくて、
pimpl がどうしても必要! と言ってる人こそライブラリ販売の世界しか見てないという話をしてんの。

774:はちみつ餃子
19/11/01 15:01:01.21 ichmHmwx.net
いる場所ではいるし、いらない場所ではいらないという当たり前のことしか言ってないつもりなんだけど。

775:デフォルトの名無しさん
19/11/01 15:04:22.58 E92xj2lK.net
全員知らないことの方が多いのに相手が自分の分野のことを知らないと無知扱いするのは草生える

776:デフォルトの名無しさん
19/11/01 16:16:45.44 luUnrp0t.net
>>759
そもそもVer. 1.0でコンパイルしたクラスライブラリをVer. 8.0でコンパイルしたオブジェクトとリンクできるの?
10年間互換性保ってるC++コンパイラの名前教えてくれるかなw

777:デフォルトの名無しさん
19/11/01 18:28:24.75 5daK08GN.net
動的リンクなら古いコンパイラでコンパイルしたライブラリが使えるかどうかはOSの互換性次第だろ

778:デフォルトの名無しさん
19/11/01 18:36:37.94 VMz8o48U.net
>>766
一般的な現象よ
周回遅れのやつに絡まれたらキョトンとしちゃうやろ
今の餃子ちゃんがまさにそれよ
幼稚園児に絡まれたお兄さんみたいになっとる

779:デフォルトの名無しさん
19/11/01 18:38:39.54 OIX3BcSW.net
あぁ、メモリーレイアウトでずっこけるやつか。

780:デフォルトの名無しさん
19/11/01 19:03:19.99 luUnrp0t.net
>>772
マングリングって知ってるか?
そもそもC++のクラスライブラリを簡単に動的リンクできるOSってあるのか?w

781:デフォルトの名無しさん
19/11/01 19:25:46.93 4VV6x0Mu.net
まんぐりがえし

782:デフォルトの名無しさん
19/11/01 19:41:21.97 N2gtvXpa.net
comはクラスライブラリになるのかな
いろいろ面倒だけど

783:デフォルトの名無しさん
19/11/01 19:44:45.43 8Rp12Rb3.net
念のため確認だけど、pimplの代替手段については把握されてる前提でOK?
URLリンク(site.oukasei.com)

784:デフォルトの名無しさん
19/11/01 19:56:12.78 o5qRV/vr.net
リンク問題はABIの話だよな?
それはリンカのオプション次第じゃないのん?

785:デフォルトの名無しさん
19/11/01 20:26:50.93 luUnrp0t.net
>>779
広い意味だとABI
リンカのオプションで前のバージョンに対応してるとかの例もあるけど10年前まで対応してる例とかあるのかな?

786:デフォルトの名無しさん
19/11/01 20:51:10.72 62eq0k7o.net
>>778
結局、pimplのI/F用外側クラスを基底クラスに、implを派生クラスにするってだけでやってることはpimplと同じ
むしろ以下の点でより悪い
・I/F用のクラスと実装用のクラスに不必要な継承関係が導入されていらない複雑度が増える
・↑と同じことだが、実装用クラスがI/F用クラスと同じメンバ関数を実装することが強制される
・コンストラクタが使えず、独自のファクトリ関数の使い方を利用者に覚えさせる必要がある
・利用者に生ポが露出する。生ポを避けたい利用者は自分でunique_ptrなどで包まなければならない
・I/F用クラスを利用者が勝手実装して混入させることを許す
上に挙げたのはポリモさせたい場合はメリットでもあるんだが、ポリモを意図しない単独クラスに継承構造なんか入れるべきではない

787:デフォルトの名無しさん
19/11/01 21:03:35.70 gYA8Bkai.net
いっそのことヘッダオンリーライブラリにしようぜ

788:デフォルトの名無しさん
19/11/01 21:04:43.68 tPmTFLHa.net
>>766
検討はずれかどうかは意見が分かれるかもしれないけど、pimplには速度的な
オーバーヘッドが少しはあるのと、記述が分かりにくいような気がするので、
個人的にはまずは使うのを躊躇する。
ポインタのワンクッションを置いても速度的なオーバーヘッドが問題ない場合には、
単純なクラスへのポインタを使ってそのクラスの実装に依存しないようなコードを書く
ことはある。しかし、pimpleと言われているものよりずっと単純なもの。
pimplの定義もよく分からないので、それが全く同じものかどうかは分からない。

789:デフォルトの名無しさん
19/11/01 21:10:39.48 gbx33EDY.net
>>752
目指す理想が違いすぎるやつとは話にならん

790:デフォルトの名無しさん
19/11/01 21:13:24.24 tPmTFLHa.net
>>778
そういう風に、C++の抽象クラス(Javaではinterfaceと呼ばれるものと等価
だったはず)を使うと分かり易いですね。

791:デフォルトの名無しさん
19/11/01 21:15:27.37 N2gtvXpa.net
実装方法もいろいろでメリットデメリットもいろいろやから好きなの使えばええねん

792:デフォルトの名無しさん
19/11/01 21:18:26.92 tPmTFLHa.net
interface を使って、データメンバを隠したい場合は、new CXxxx にあたる部分を
どうやって実装するかの問題になるんですね。グローバル関数にしてしまう
方法もありますが、確か、デザインパターンの「Factoryパターン」というものが
それに該当したかもしれません。

793:デフォルトの名無しさん
19/11/01 21:34:43.52 aQLx28Zt.net
>>768
依存切りたいならpimplと言ってるところに
依存気にしてないからpimpl不要っていってるのがお前
不要ならすっこんでろって

794:デフォルトの名無しさん
19/11/01 22:03:59.28 p6e3QfJv.net
COM最強やな

795:デフォルトの名無しさん
19/11/01 22:07:08.70 tPmTFLHa.net
>>789
めちゃくちゃ使いにくい。

796:デフォルトの名無しさん
19/11/01 22:10:22.26 U/a7Wx11.net
>>784
目指す理想がpimpl?
確かに話にならんなw

797:デフォルトの名無しさん
19/11/01 22:13:09.54 U/a7Wx11.net
>>790
ただ20年間I/F変えないようにするにはあの程度の手間は必要なわけで
まあもうちょいスマートにできるんじゃないかなって思うところは多々あるけど


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch