C++相談室 part145at TECH
C++相談室 part145 - 暇つぶし2ch262:
19/10/01 23:32:20.09 3zNRBOOL.net
>>253
1個のプログラムの中に一個か二個の float しか使わなくても、 double の場合より速くなるのですか?
そもそもイントリンシックを書かないのに SIMD のコードが出力されるのですか?
私は、コンパイラは fpu のコードしか吐かないじゃないか?って考えています

263:デフォルトの名無しさん
19/10/01 23:37:45.74 KZgN44vw.net
>>261
それはお前の頭が老害だから

264:デフォルトの名無しさん
19/10/01 23:39:09.19 84uW7JaU.net
速さ計測すればいいじゃん
逆アセンブル見ればいいじゃん

265:
19/10/01 23:40:49.69 3zNRBOOL.net
>>262
1個のプログラムの中に一個か二個の float しか使わなくても、 double の場合より速くなるのですか?
そもそもイントリンシックを書かないのに SIMD のコードが出力されるのですか?

266:デフォルトの名無しさん
19/10/01 23:44:09.36 sOAgszt0.net
そもそもx64ではFPUは無かったことにされている
doubleやfloatの計算したかったらSIMDで1レーンだけ使って計算する仕組み

267:デフォルトの名無しさん
19/10/01 23:54:05.20 5ranOfZi.net
>1個のプログラムの中に一個か二個の float しか使わなくても、 double の場合より速く
その条件だとどっちを使っても良い大して変わらん
やっぱループアンローリングできるぐらいループリッチな課題でないと意味が無い
URLリンク(www.isus.jp)
URLリンク(cpplover.blogspot.com)

268:デフォルトの名無しさん
19/10/02 00:10:27.89 eo8nmuYy.net
しかしコンパイラの最適化はイマイチっぽい
URLリンク(www.isus.jp)

269:
19/10/02 07:48:44.41 BafSfR+Q.net
>>265
いいえ x64 でも fpu コードは使えますよ、嘘はやめて!

270:デフォルトの名無しさん
19/10/02 07:54:44.99 Y2eIpMbX.net
>>228
こういうやつって何かしらソフト完成させたこともない初心者のクセしてイキってるんだろ
マジ邪魔だから消えて欲しい
テンプレート使ったコードで遅くなるというのがわからんならboostのspiritとか使ってみたらいいわ
言ってる意味わかるから

271:デフォルトの名無しさん
19/10/02 07:59:03.00 Y2eIpMbX.net
あ、もちろんデバッグビルドの話な
最適化ありならspiritは当然速い

272:デフォルトの名無しさん
19/10/02 08:01:33.95 sddCZQNP.net
C++を使わないと言っているやつに、どうぞご勝手にということと何の関係が?

273:デフォルトの名無しさん
19/10/02 08:22:40.25 QmwKmz4W.net
>>268
でもアセンブラで直接使わないと無かったことにされるだろ

274:デフォルトの名無しさん
19/10/02 08:29:18.29 0zoKeqvU.net
>>261
amd64でfpuコード吐かせるほうが手間じゃwwww

275:デフォルトの名無しさん
19/10/02 08:30:44.39 0zoKeqvU.net
そもそもプログラム中に一個か二個の浮動小数点演算なんて最適化ポイントちゃうがなwwww
自説を通すためにバカな例を仮定するアホに絡むだけ無駄やなw

276:デフォルトの名無しさん
19/10/02 11:21:30.36 iITLzrzf.net
>>272
プロジェクトの設定でfpも選べるよ
既定だとsse使われると思うけど

277:デフォルトの名無しさん
19/10/02 22:05:22.14 VK3sSC9+.net
コンパイラの種類変わったら算術演算ぶん回す場合は結構差が出るだろうけど、同じコンパイラでバージョンかわると最適化とかの進化で結構かわるのかな?
gccの3と4、msvcの2005と2017とかそういう違いで

278:デフォルトの名無しさん
19/10/03 04:57:05.82 vAL7lUst.net
質問です
既にクラスHogeとAがあり
クラスAとは別に新たにクラスBを追加することになった
BはA専用の関数が無く呼び出す必要も無いし逆のことは無い
その場合BにA専用の関数と同じ名前の空の関数を用意するか、呼び出されているHoge内で切り分けるかどちらの方が良いですか?
なおAは絶対に継承しなければならないし改変することもできない
class Hoge : A か class Hoge : Bをプリプロセッサかテンプレートで切り分ける
これを
void Hpge::func() {
  A_func(); //Bは持っていない
}
プリプロセッサで切り分けるのが良いのか
void Hpge::func() {
#if defined(USE_A)
  A_func();
#endif
}

それとも空の関数を書いた方が良いのか
class Hoge : B {
  A_func() {}
}
詳しい方がいたら教えていただきたいです
これ以外の賢いやり方があればそれでも大丈夫です

279:デフォルトの名無しさん
19/10/03 07:04:32.42 damPur2/.net
絶対に、の理由が知りたいところだけど、普通はA_funcを仮想関数にしてBは空関数でオーバーライド。

280:デフォルトの名無しさん
19/10/03 07:05:22.94 OJdSM3QH.net
c++17以降ならif constexprとstd::is_sameでできるんじゃない?
template < typename T >
class Hoge : T{
void func() {
  if constexpr(std::is_same<T,A>){ //基底クラスTがAであればA_func()を実行する
    A_func();
  }
}
}

281:デフォルトの名無しさん
19/10/03 07:12:55.92 OJdSM3QH.net
std::is_same<T,A> じゃなくて std::is_same_v<T,A> か

282:デフォルトの名無しさん
19/10/03 07:31:04.45 5EMHpFEj.net
>>278
HogeがAかBを継承するんだからそれじゃだめやろ
ただ設計見直したいところだけどそういうわけにもいかんのかね

283:デフォルトの名無しさん
19/10/03 07:54:23.64 r73Y/293.net
c++17が使えなくて、Bの定義を関係ないAのために汚染したくないなら一層増やせばいい
template<typename T>
class HogeBase;
template<>
class HogeBase<A> : A {}
template<>
class HogeBase<B> : B { A_func(){} }
template<typename T>
class Hoge : HogeBase<T> { /*...*/ }

284:デフォルトの名無しさん
19/10/03 09:13:02.91 r91xqmRv.net
>>2


285:81 なにか問題起きる?



286:デフォルトの名無しさん
19/10/03 11:57:14.92 z1c5xmGq.net
>>277
基底クラスを切替たいってこと?
しかも片方の基底クラスにしかないメソッドを派生クラス側で呼出すとかどんな状況なんだろう…
まあ、やっつけでやるなら素直にB側に空のメソッド追加しとけばいいと思うよ
どう見てもまともな設計じゃなさそうだし、かと言って設計を見直すこともできなさそうだしね
プリプロセッサなんて愚の骨頂にしかならん

287:281
19/10/03 12:22:59.66 GJuckdYX.net
>>283
A_funcを持つものを継承するならオーバーライドが理想的だろうけど、基底がAかBってことだから無理っしょ
しかもAは書き換えられないときてる
すでに言われてるようにテンプレートで基底を指定させるか単純に空のA_funcを書くか、プリプロセッサか
でもそもそも利用者側がAを使うのかBを使うのか決めるのなら、クラス側で対処せずに利用者がプリプロセッサで分けた方がいいと思う(でないとぐちゃぐちゃになりそう)
それだと修正箇所が多すぎるのかもしれんけど

288:デフォルトの名無しさん
19/10/03 13:00:06.78 t4NBMq8s.net
こんなマトモじゃないケースに
ベストな解答なんかないわな

289:デフォルトの名無しさん
19/10/03 13:00:33.56 YSTER/9m.net
>>284
Qtをdisってんの

290:デフォルトの名無しさん
19/10/03 15:51:04.04 z1c5xmGq.net
まさかと思うがQtを盲信してるのか?w

291:デフォルトの名無しさん
19/10/03 16:04:15.58 LjcEi/T6.net
ちょとっ猛進

292:デフォルトの名無しさん
19/10/03 16:37:32.38 vAL7lUst.net
回答ありがとうございます
プリプロセッサまみれになるより空の関数生やした方が見通しよさそうですね

293:デフォルトの名無しさん
19/10/03 18:04:25.67 SL8wP/0a.net
>>288
え、qt便利じゃん

294:デフォルトの名無しさん
19/10/03 19:00:51.01 BEqWQnsI.net
旧版は知らんけどQt5はかなり良いと思う
不満に思うのはベンチ厨くらいでは

295:デフォルトの名無しさん
19/10/03 19:22:01.27 z1c5xmGq.net
>>291
便利かどうかなんて言ってないのにいきなりどうした?w

296:デフォルトの名無しさん
19/10/03 21:53:13.09 Uq6PP8Ux.net
コンパイル通らないので助けてください。
メンバテンプレートを持つクラスを継承して、派生先からメソッドが呼べません。
一見問題なさそうにはみえるのですが・・・
template<typename _T1>
class A{
public :
template<typename _T2> _T2 get() { return _T2(); };
};
template<typename _T3>
class B : public A<_T3> {
std::string hogehoge() { return A<_T3>::get<std::string>();}
};

297:デフォルトの名無しさん
19/10/03 21:59:37.34 A/fPHEZe.net
>>294 エラーメッセージとか出てないの?

298:デフォルトの名無しさん
19/10/03 22:06:09.67 BrhogHgJ.net
>>294
clangさんが教えてくれた
std::string hogehoge() { return A<_T3>::template get<std::string>();}

299:デフォルトの名無しさん
19/10/03 22:13:42.78 Uq6PP8Ux.net
ありがとうございました。
通りました。
つか、そんなtemplate文の使い方初めて知った・・

300:デフォルトの名無しさん
19/10/03 22:31:15.90 zkquM/gX.net
この場合Aがテンプレートなので、Aの先のgetが何者かコンパイラは判断つかないので
"<" が比較演算なのかテンプレートのかっこなのか判断つかないから
らしい
clangは教えてくれるんだから判断ついてるわけだが・・・
まったく醜い文法を持った言語だよ

301:デフォルトの名無しさん
19/10/03 22:49:50.59 BrhogHgJ.net
この場合のエラーメッセージ、GCCはほんとに何言ってるのか分からないのを出すのでclang様様

302:デフォルトの名無しさん
19/10/04 01:11:35.70 gSpEwnzq.net
C++テンプレートのプログラミングでのエラーを読み解く訓練をしているうちに
実世界での初心者が投げてくる質問へのエスパー力がやしなわれる
これ豆

303:デフォルトの名無しさん
19/10/04 02:30:32.92 gpJXYiEy.net
そのうちエラーメッセージを見ずにエラーを修正できるようになる

304:デフォルトの名無しさん
19/10/04 02:54:08.89 P4b1n6up.net
ちなVC2015か2017か忘れたけど、一時期までのVCは
その場合のtemplateを書くと逆にエラーにされてた

305:デフォルトの名無しさん
19/10/04 03:18:41.39 I4catYuR.net
goで変数用いて
*******
*****
***
*
***
*****
*******
って出力するにはどうすりゃいいのっと

306:デフォルトの名無しさん
19/10/04 03:19:28.61 I4catYuR.net
あ、↑のは砂時計みたいな形にしたい

307:蟻人間
19/10/04 04:12:53.14 NaWoGk/Z.net
>>303
二重のループか仮想画面

308:デフォルトの名無しさん
19/10/04 04:19:18.14 I4catYuR.net
>>305
申し訳ないが初心者ゆえ、数字の二重ループはできるけどそれを文字列にする仕方がわからず

309:デフォルトの名無しさん
19/10/04 05:45:45.52 jwb6jSs+.net
goスレ行け

310:デフォルトの名無しさん
19/10/04 08:20:48.47 FzFdUbJu.net
>>298
なぜか偶然ですが、このスレを見る前から昨日からその辺に関係するパーサーを
作っていて悩んでいたところなんですが、
多くの言語では、+,-,*,/,<,> などの演算子が混ざったいわゆる「数式」は文脈に依存せずに
上位のコンパイル作業に入る前に、いったん「数式ツリー」に直すことが出来ます。
ここで「文脈に依存せず」というのは、変数名、関数名、型名などの宣言情報を
調べなくても済むという(いわゆる意味解析の結果の情報を必要としないと言う
)ことです。
ところが、template機能が入った後のC++では、A<B と書いたとき、
< がテンプレートの記号なのか比較演算子なのかは A がテンプレート名であるか
どうかによって決まります。
Bが型名であることが明確な場合には文脈によらず < はテンプレート記号だと断定
できます。ところが、Bに 1, 456, 3.1415 のような数値や、"Hello" などの文字列
が来ている場合には、(その場では)判断が付きません。
文脈に依存せずに判断を付けたいなら、もっと先まで呼んで、< に対応する >
があるかどうかを調べるといける可能性があります。
1. "<"に対応する">"が存在するかどうか調べれば、これまでの宣言情報を使わなくても
 トークン・ツリーを作ることが出来る。トークン・ツリーと言ったのは、数式とは
 限らないからです。例えば、A<B> x[100]; などとすることがありますが、A<B>
 は型名であり、数式では有りません。ただし、他の多くの言語では数式ツリーは
 作ることが多いのですが、トークン・ツリーはまず作りません。
2. 1の方法を使わないなら、宣言情報を調べて、Aがtemplate名であるかどうかを調べる
 必要がある。ところが、Q::A<B> などのような場合があるので、そんなに
 単純な作業でく、Q::A が型名なのか、変数名なのかはちゃんと調べる必要がある。

311:デフォルトの名無しさん
19/10/04 08:25:56.64 FzFdUbJu.net
>>308
補足
「Bが型名であることが明確な場合には文脈によらず < はテンプレート記号だと断定
できます。」
の部分ですが、B<CPerson(実引数列) などとした場合、CPersonは型名ですが、
CPerson(実引数列) 全体は、型名ではなくCPersonクラスの引数つき
コンストラクタを呼び出した結果の「一時オブジェクト」です。なので、
Bが変数名の場合は、< は比較演算子の可能性があります。

312:デフォルトの名無しさん
19/10/04 08:33:37.62 FzFdUbJu.net
>>308
誤:なぜか偶然ですが、このスレを見る前から昨日からその辺に関係するパーサーを
正:なぜか偶然ですが、このスレを見る前の昨日からその辺に関係するパーサーを
誤:文脈に依存せずに判断を付けたいなら、もっと先まで呼んで、< に対応する >
正:文脈に依存せずに判断を付けたいなら、もっと先まで読んで、< に対応する >
誤:単純な作業でく、Q::A が型名なのか、変数名なのかはちゃんと調べる必要がある。
正:単純な作業ではなく、Q::A がtemplate名なのか、変数名なのかはちゃんと調べる必要がある。

313:デフォルトの名無しさん
19/10/04 08:37:14.54 P4b1n6up.net
>>225
>>224=228や>>226=219みたいなどうみても初心者なヤツにプロが敬語使う必要ないと思うよ
C++スゲー=俺スゲーみたいな明らかにプログラミングに向いてない精神構造のクソバカが多く居るからねここ

314:デフォルトの名無しさん
19/10/04 08:41:34.48 FzFdUbJu.net
>>306
一般論として、文字列の長さを len として、文字列型の変数を str としたとき、
for ( len 回のループ ) {
 str = str + "*"
}
で行けます。

315:デフォルトの名無しさん
19/10/04 09:33:34.23 8yIxxMU3.net
>>311
ようクソバカ

316:デフォルトの名無しさん
19/10/04 09:41:54.97 P4b1n6up.net
>>313
すまんな図星だったか?
邪魔だから出てけよ

317:デフォルトの名無しさん
19/10/04 11:43:51.24 FzFdUbJu.net
>>308
C++言語をパースする方法として、結論的には、2.ではダメで、1.でなくてはならないようです。例として、A<実引数列>::B の場合を考えると、template は実体化する
際の実引数によって展開される内容は大幅に変わりますので、
A<int>::B とした場合には、B は template 名で、
A<string>::B とした場合には、B は変数名であることもありえます。すると、
A<int>::B<C> の場合の B<C> は template 実体化ですが、
A<string>::B < C の場合は、変数B と変数 Cに対しての比較演算となります。
なので、もし、>>308 の 2.のやり方でパース使用とすると、Aがtemplate名であると
分かっただけでは B が「何なのか」を結論付けるには不十分で、A<実引数列>の
実引数列をほとんど完全に調べ上げてから、その方名に応じた template A の
定義を探して template の overload 解決をしてから、A<実引数列> 部分(のclass)を
完全に「特定」する必要があります。ここまでやるとなると、コンパイラの層分けが
上手く出来ないことになります。

318:デフォルトの名無しさん
19/10/04 12:03:58.19 FzFdUbJu.net
>>315
A::B くらいの場合なら、意味解析の情報だけを元に、Bが何なのかを特定をすることは
可能です。ところが、A<1+2,decltype(x*y)>::B の様な場合、x, y の意味論的な型
を調べた後、x*yに適応可能な operator*() 関数が定義されて言うかどうかも調べ、
定義されていれば、その戻り値の型を調べてx*y の型として、A<・・・> の部分が
結局何なのかを特定しなくてはなりません。今述べた x*y の部分の処理は、
トークン解析層(?)より上位のコンパイル層で行う処理です。なのでこのやり方
だと、コンパイラ内部の「層」の切り分けが難しくなります(技術的に不可能な
わけではありませんが。)。

319:デフォルトの名無しさん
19/10/04 12:07:27.45 FzFdUbJu.net
>>315
誤:なので、もし、>>308 の 2.のやり方でパース使用とすると、Aがtemplate名であると
正:なので、もし、>>308 の 2.のやり方でパースしようとすると、Aがtemplate名であると
誤:実引数列をほとんど完全に調べ上げてから、その方名に応じた template A の
正:実引数列をほとんど完全に調べ上げてから、その型名に応じた template A の
>>316
誤:を調べた後、x*yに適応可能な operator*() 関数が定義されて言うかどうかも調べ、
正:を調べた後、x*yに適応可能な operator*() 関数が定義されているかどうかも調べ、

320:デフォルトの名無しさん
19/10/04 12:36:35.66 cK/f4a5x.net
>>312
ありがとうございます!
やってみます

321:デフォルトの名無しさん
19/10/04 12:41:17.15 G1/ISgxb.net
c++って文法に曖昧さがないことどうやって保証してんだろ
形式的なアプローチ無理だと思うんだが

322:デフォルトの名無しさん
19/10/04 13:05:22.64 MVQV/kgg.net
いや、そんな保証は端っから諦めてるだろ
引数なしの関数宣言とデフォコン呼び出しの曖昧さなんか
長年放置してたのをC++11でようやく対応したし
関数ポインタにキャストするoperatorはtypedef使えとか
言語としての完全性なんか重視してない

323:デフォルトの名無しさん
19/10/04 13:28:40.80 FzFdUbJu.net
>>319
曖昧さはあるといわれています。例えば、CPersonというクラスがあったとき、関数内で
CPerson person();
と書いた場合、person という名前で、戻り値の型が CPerson の関数のプロトタイプ宣言なのか、
CPerson クラスの person という変数名(オブジェクト名)の定義なのかの曖昧さがあります。
後�


324:メは、CPerson person("name", 25, MALE); などと同じ系統で、実引数が全く無い場合 に相当します。 また、template class の場合に、 A<B<・・・>> と書くと、>> が右シフト演算子に解釈されてしまうので、回避するために空白を1つ入れて A<B<・・・> > としなければならなかった(過去形)時代も有ります。 しかし、パーサーを作る側からすれば、">>" を ">" 2個 だと解釈するのはかなり大変な 労力が必要でです。 また、x < y を比較演算のつもりで A< x < y > などと書くと、A<・・・> の中に x という template class 名に対しての x<y> が入っていると解釈 されてしまい、> が足りないというエラーになるかもしれません。 回避するには、 A< (x < y) > と書くと良いと思われます。



325:デフォルトの名無しさん
19/10/04 14:48:30.02 D8qarNFk.net
C++というより3Dプログラミングの質問で申し訳ないのだけど、
行列ライブラリglmの以下のコードがbugってる気がするので詳しい人がいたら確認して欲しい。
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
{
vec<3, T, Q> Tmp = v;
// Axis of rotation must be normalised
T len = glm::length(Tmp);
if(abs(len - static_cast<T>(1)) > static_cast<T>(0.001))
{
T oneOverLen = static_cast<T>(1) / len;
Tmp.x *= oneOverLen;
Tmp.y *= oneOverLen;
Tmp.z *= oneOverLen;
}
T const AngleRad(angle);
T const Sin = sin(AngleRad * static_cast<T>(0.5));
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
}
クオータニオンqをベクタ軸v周りにAngleRad回転させる関数のソースらしいんだが、
最後の行掛け算の順番が逆のような気がする。
qua<T,Q>(...) * qが正解だと思うんだ。
glmはファイル構成がバージョン間で結構派手に変更されてるんで、
最近のバージョンではext/quaternion_transform.inlに上のコードが含まれてる。
古いバージョンではgtx/quaternion.inlにあったような気がする。

326:デフォルトの名無しさん
19/10/04 14:55:11.92 FzFdUbJu.net
>>322
あるライブラリでのq1 * q2 という書き方が、q2 * q1
がどういう意味に解釈されるかは、

327:デフォルトの名無しさん
19/10/04 15:01:05.28 FzFdUbJu.net
>>322
(>>323 は誤投です。)
あるライブラリでの q1 * q2 という書き方が、別のライブラリでは
q2 * q1 と等価なことが有り得て、それはベクトルや行列計算全般に
言える記法の違いなのでこのソースだけではなんとも言えない。
ベクトルの場合、成分表示を1列の縦行列と考えるか1行の横行列
と考えるかによって、賭け全の左右が逆さまになる。
その結果、成分表示で書かない表記も、左右どちらかで書くかは
好みの問題となる。
特に Quaternion の場合も同様。

328:デフォルトの名無しさん
19/10/04 15:02:02.33 FzFdUbJu.net
>>324
誤:と考えるかによって、賭け全の左右が逆さまになる。
正:と考えるかによって、掛け算の左右が逆さまになる。

329:デフォルトの名無しさん
19/10/04 15:45:42.88 P4b1n6up.net
OpenGL系は縦ベクトルだね
D3Dを前提にしたライブラリとは逆になる(行列も転置

330:デフォルトの名無しさん
19/10/04 15:58:00.91 FzFdUbJu.net
>>326
数学や物理学では縦ベクトルが多いが、D3Dはそれに従ってない。

331:デフォルトの名無しさん
19/10/04 16:08:07.51 JXWhYfPM.net
テンプレが糞だと思う瞬間はいくつもあるが
その一つはネストしてるときの閉じ括弧
>> じゃだめで > > ってわざわざ分けないといかんうざい

332:デフォルトの名無しさん
19/10/04 16:08:35.30 P4b1n6up.net
>数学や物理学では縦ベクトルが多いが、D3Dはそれに従ってない。
みたいだね
D3Dからそれ以外に移るとみんなここで引っかかるけど
実は行列周りは(大文字は行列として)
OpenGLに合わせるとA*B*C*xとなるのを
D3Dではx*C*B*Aと書けた方が、左からの計算が全部結果がベクトルなので計算量が減るというメリットはある
MSはC++での書きやすさと効率を考えたのかもしれない

333:デフォルトの名無しさん
19/10/04 16:09:02.58 JXWhYfPM.net
>>326-327
縦横ってより右から掛けるか左から掛けるかだと思ってた
意味は一緒なんだろうけど

334:デフォルトの名無しさん
19/10/04 16:11:58.82 P4b1n6up.net
>>328
C++11からは連続して書けるようになったで

335:デフォルトの名無しさん
19/10/04 16:14:31.61 MVQV/kgg.net
C++03いやC++98?のまま更新止まってるやつ
俺が想像するより遙かに多いのかもしかして
もうC++11でさえ要注意な旧規格になってるんだが

336:デフォルトの名無しさん
19/10/04 16:16:30.52 JXWhYfPM.net
>>329
メモリ上の順序も変わるぞ
SIMDとかで計算されるときの効率にも影響する
必ずしもD3D(横ベクトル方式)が高速化に都合が良いとは言えないんじゃないか
行列の各要素のメモリ上の並びって
glの行列AとD3Dの行列A'はいちいち転置しなくても結局同じになるんだっけ

337:デフォルトの名無しさん
19/10/04 16:22:07.03 P4b1n6up.net
ああ確かにメモリの中身は同じだった
格納方式も違うから結果的に同じになるんだよね
そこが余計ややこしい

338:デフォルトの名無しさん
19/10/04 16:29:39.34 FzFdUbJu.net
>>329
行列計算は、縦ベクトル方式、横ベクトル方式でも、(それぞれで)「結合則」があるので、
A*B*C*x = A*(B*(C*x))
でもあり、
A*B*C*x = ((A*B)*C)*x)
でもあり、どっちで計算しても結果は同じになる。
また、3D計算の場合、点の座標がいくつあっても、行列を一度計算しておくと、
使いまわしできるので、先に行列の方を計算しておいて、最後に座標の変換
を行うと、点が2個以上あるときには効率が高い。

339:デフォルトの名無しさん
19/10/04 16:31:49.50 FzFdUbJu.net
>>332
C++98くらいから、実際問題上使いたくない機能ばかりが追加されるような
傾向があったのに、Upgrade 版は適用外になったりしたりして買う機を逃した。

340:デフォルトの名無しさん
19/10/04 16:38:53.10 FzFdUbJu.net
>>329
>MSはC++での書きやすさと効率を考えたのかもしれない
>>335 に既に書いたけど、OpenGL 形式でも、右結合でも、
左結合でも、好きな方で計算は出来る。だから、行列部分を
先に計算しても良いし、座標部分から計算しても良い。
座標部分から計算していくと一見計算量が減るように思える
かも知れないが、点の個数が多くなると、一度だけ行列部分の
積を予め計算しておいて、その結果を全ての点の変換部分に
遣うと効率が劇的に向上するので、むしろ、効率が良いのは逆。

341:デフォルトの名無しさん
19/10/04 16:40:53.55 P4b1n6up.net
>>335
確かに(OpenGLでも上で書いたような式が使えるライブラリ使うとして)括弧でくくったりして優先順位変えればいいし
言う通り行列はまとめればいいんだけど
どちらにもメリットデメリットあると言いたかった

342:デフォルトの名無しさん
19/10/04 16:51:20.07 FzFdUbJu.net
>>338
実は、アメリカで有名な 3D Graphics の本が、横ベクトル方式を採用していた
事が関係しているかもしれない。要はその本が数学や物理の標準とは何故か
逆の記法を採用していたということ。

343:デフォルトの名無しさん
19/10/04 17:00:49.77 FW+Y/3wm.net
>>337
GL
(A*B*C)*(x0(縦),x1(縦),x2(縦),x3(縦), ... , xN(縦))(横)
D3D
(x0(横),x1(横),x2(横),x3(横), ... , xN(横))(縦)*(C*B*A)
が最速やね

344:
19/10/04 19:54:25.76 5CiM54x6.net
>>335
行列って結合則は約束されてましたっけ?

345:デフォルトの名無しさん
19/10/04 20:17:27.71 gZky9oRw.net
当たり前だろ。
そんなレベルの知識しかないからフォントライブラリ書けないんだよ

346:
19/10/04 20:27:59.81 5CiM54x6.net
>>342
では証明してください(キリッ)

347:デフォルトの名無しさん
19/10/04 21:24:32.75 FzFdUbJu.net
>>343
ベクトル部分はおいておくとして、まず正方行列の部分だけに限定すれば
A(BC)=(AB)C  ・・・(1)
が証明できれば どんな場合でも結合側が成り立つことが数学的帰納法で
証明できます。なので、A,B,C が正方行列の時に(1)を証明すれば全体の証明が
ほぼ終わります。
【(1)の証明】
行列の積の定義により
 (AB)ij=Σ_{k=1}^n A_{ik} B_{kj}  ・・・(2)
です。なので、
{(AB)C}mn = Σ_l(AB)_{ml}C_{ln}
     = Σ_k Σ_l A_{mk} B_{kl} C_{ln} ・・・(3)
です。全く同様に、
{A(BC)}mn = Σ_k A_{mk} (BC)_{kn}
     = Σ_k A_{mk} Σ_l B_{kl} C_{ln}
     = Σ_k Σ_l A_{mk} B_{kl} C_{ln} ・・・(4)
となり、(3), (4) が一致することから、
 {A(BC)}mn = {(AB)C}mn
が言えます。これが (1) に他なりません。    (Q.E.D)
次に、このように3つの行列の場合ではなく、一般の個数の行列の場合、
最初に書いたように数学的帰納法を使います。それは、あなた自身で
お考えください。考える力の練習になります。

348:デフォルトの名無しさん
19/10/04 22:10:52.87 cDY60lSZ.net
doubleの値を++aした時にaの値は+1と規定されてる?

349:デフォルトの名無しさん
19/10/04 23:19:26.96 FzFdUbJu.net
>>345
boolen型以外では、++x は正確に x+=1 と等価です。
x+=1 は、正確に x = x + 1 と等価です。x がポインタ型の場合は、
BYTE 単位で見ると object size 単位で増加しますが、double/float/int/short/char
などの「算術型」の場合は、単純に 1 が足されるだけです。

URLリンク(en.cppreference.com)
For non-boolean operands, the expression ++x is exactly equivalent to x += 1, and the expression --x is exactly equivalent to x -= 1, that is, the prefix increment or decrement is an lvalue expression that identifies the modified operand.

350:デフォルトの名無しさん
19/10/04 23:36:52.32 NJj/Utu/.net
>>346
ありがとうございます。
という事はキャストの時におかしくなっているのかな?
aの値は0.0~100.0程度
for(double i = a; i < 1000.0; ++i){
std::cout << (int)i << "," << std::endl;
}
期待している結果: 1,2,3,4,5...と連番になる
たまに起こる結果: 1,2,3,5,6...と歯抜けになる

351:デフォルトの名無しさん
19/10/04 23:42:33.92 8yIxxMU3.net
丸められただけでは

352:デフォルトの名無しさん
19/10/04 23:55:23.10 YWySipM2.net
>>341-344
また5ch名物のしょーもない煽り煽られの流れかとおもったら
ちゃんと勉強になる流れでワロタ

353:デフォルトの名無しさん
19/10/05 00:03:15.79 bnoeYdBm.net
行列の結合則なんて高校で習っただろ
線形代数わからないプログラマって生き残れないと思うわ

354:デフォルトの名無しさん
19/10/05 00:05:26.41 KADe2ROY.net
>>347
・そのコードは、完全に上記の通りですか?
例えば、ループ回数が1000回より遥かに多くなると、
誤差の都合でそうなることがあるかもしれませんが、1000回くらい
だと、正しい処理系ではその現象は起きないはずです。

355:デフォルトの名無しさん
19/10/05 01:17:38.13 d5aP5JOP.net
キャストする前にlround呼んだらええんちゃうん。

356:デフォルトの名無しさん
19/10/05 01:44:04.24 VkhEKreX.net
(0.2+0.3)+0.4 == 0.2+(0.3+0.4)の結果がfalseになるのは正しいの?

357:デフォルトの名無しさん
19/10/05 01:54:00.97 Lbi5NeET.net
浮動小数点を勉強しておいで

358:デフォルトの名無しさん
19/10/05 02:07:17.64 5hJZ4CgN.net
有効数字1桁の計算で誤差は生じない

359:デフォルトの名無しさん
19/10/05 07:04:22.03 UfPJq4d2.net
10進の0.1を2進表現すると循環小数定期
>>355
バカ乙

360:デフォルトの名無しさん
19/10/05 08:03:13.32 9T2eUTn8.net
>>336
本当、人って色々だな
俺はC++98は未完成感があまりに強くて続きはまだかと待ちかねていた
具体的には例えば右辺値参照だ
一時オブジェクトにいちいちconstがつくのがイヤでイヤで待望のやつがやっと来た

361:デフォルトの名無しさん
19/10/05 08:28:45.86 iS4eZEWC.net
>>337, >>340
ちょっと誤解招くのでやっぱ突っ込んでおくけど、
多数のベクトルを変換するのに行列をまとめておかないと無駄になるのはどっちの方式でも同じだよ
俺が言ったのは(少なくとも同一の行列が)一度限りしか出てこない場合の話
まぁそれを最適化する必要があるのか、またそういう処理を大量にループするなら最適化の方法は他にあるだろうけど
>>333
GL方式でも列優先だから結局d3dと同じ無駄はあるんやで
最近のは知らんけど

362:デフォルトの名無しさん
19/10/05 08:49:33.11 KADe2ROY.net
>>353
計算誤差です。
(0.2+0.3)+0.4 == 0.2+(0.3+0.4) が偽になっても
(0.2+0.3)+0.4 == (0.2+0.3)+0.4 や
0.2+(0.3+0.4) == 0.2+(0.3+0.4)
は必ず真になることが保障されています。

363:デフォルトの名無しさん
19/10/05 08:55:38.66 KADe2ROY.net
>>359
コンピュータにおける浮動小数点は、内部表現は10進数ではなく2進数
で表現されており、有効桁数は 10 進数で 8 桁や 15桁などではなく
2進数で xx BIT という風になっています。
0.2, 0.3, 0.4 は、10進数だと、有効桁数が1桁でも完全に区切れが
よく表現できていますが、2進数の表現だと厳密には無限小数になってしまい、
どんなに有効桁数を長くしても厳密には表現できません。そのため計算誤差
が生じるのです。0.5 や 0.25 や 0.125 は 2 進数でも区切れ良く表現できるため、
 (0.125+0.25)+0.5 == 0.125+(0.25+0.5)
は誤差が生じることがないため、必ず真になるはずです。

364:デフォルトの名無しさん
19/10/05 10:06:32.18 e1uvrqu3.net
>>360
浮動小数の計算誤差を考慮して比較する時にstd::abs(a-b) < std::numeric_limit<double>::epsilon()というふうにするのはどう思う?

365:デフォルトの名無しさん
19/10/05 11:34:20.93 KADe2ROY.net
>>361
誤差の量が計算の順序や書き方によって変わってくるので、
そのようなヘッダに書かれているような誤差定数を使うことは
余り意味がありません。

366:デフォルトの名無しさん
19/10/05 11:37:49.72 7pdQvekm.net
実用数学

367:デフォルトの名無しさん
19/10/05 11:43:08.23 rY1OpV0v.net
>>361
機械イプシロンはそういうふうに使うものじゃない

368:デフォルトの名無しさん
19/10/05 12:09:22.39 uol03Q2n.net
cpprefjpが>>361と全く同じ間違いしてたわ馬鹿が湧くのはこいつのせいか
cppreference.comは正しかったからそっち見れ

369:デフォルトの名無しさん
19/10/05 12:34:57.85 dFaPF8AB.net
>>365
x-yの元になっているxやyがどのような計算過程を経てきたかわからないのに
 std::abs(x-y) <= std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
でxとyがalmost equalsと言い切ってよい根拠とは、
ちゅか常識的に考えて、x、yがそれぞれ±e、±gの誤差を有するなら
 std::abs(x-y) <= std::numeric_limits<T>::epsilon() * (std::abs(e) + std::abs(g))
あたりの判定に落ち着かねばおかしい(これで正解とは言っていない
なんでstd::abs(x+y)みたいな場合によっては莫大な値になりえる係数を掛けねばならないの?

370:デフォルトの名無しさん
19/10/05 13:04:02.75 rY1OpV0v.net
イプシロンに誤差を掛けても意味ない。
つか、許容誤差の絶対値が与えられているならイプシロン使う必要もない。
cppreference.comのは許容誤差をULP単位で与える場合のやりかたで、
abs(x+y)はxとyの指数のうち大きい方を意味するものだったはず。

371:デフォルトの名無しさん
19/10/05 13:12:59.71 uol03Q2n.net
>>366
なんか色々根本的に勘違いしてる
cppreference.comのalmost_equal関数の仕事はあくまで与えられたxとyがalmost equalかどうかの判定だよ
> x、yがそれぞれ±e、±gの誤差を有するなら
なにこれ?「誤差」って何に対する何の誤差?

372:デフォルトの名無しさん
19/10/05 13:28:00.03 dFaPF8AB.net
>>367
>イプシロンに誤差を掛けても意味ない。
>つか、許容誤差の絶対値が与えられているならイプシロン使う必要もない。
左様ですなスマンカッタorz
>>368
>なにこれ?「誤差」って何に対する何の誤差?
真の値に対する誤差じゃわパオーン
真の値に対する誤差に依存しないalmost equal判定とか、使いどころはきわめて限定されるはず、

373:デフォルトの名無しさん
19/10/05 14:05:34.77 dFaPF8AB.net
>abs(x+y)はxとyの指数のうち大きい方を意味するものだったはず。
xが (xの符号)×1.bbbb...×2^m
yが (yの符号)×1.cccc...×2^n
だとしたときに、m>nだとすると
 x + y =
 { (xの符号)×1.bbbb... + ((yの符号)×1.cccc...×2^-(m-n)) } ×2^m
として計算されるのでだいたい2^m(x≒yなら2^(m+1))という意味か左様か、

374:デフォルトの名無しさん
19/10/05 14:08:05.45 dFaPF8AB.net
んまーulpをxとyの来歴に応じて調整すべき量とするなら
cppreference.comのalmost_equal関数は理解してやらないでもない

375:デフォルトの名無しさん
19/10/05 16:03:17.50 NXndjuW4.net
だれか、俺に分数を教えてくれないか?
足し算と引き算がマジ解らなくなってるんだ。
URLリンク(ideone.com)
一番のネックはネガフラグの扱い。
マイナスとプラスの反転演算でどうかくとスマートだろうか。
だれか教えてプリーズ。

376:デフォルトの名無しさん
19/10/05 16:21:25.21 bnoeYdBm.net
分子に符号もたせりゃいいだろ

377:デフォルトの名無しさん
19/10/05 16:25:36.94 NXndjuW4.net
>>373
え、それでよかったっけ?

378:デフォルトの名無しさん
19/10/05 16:34:31.54 hwiNAqBO.net
>>350
今習わないよ
俺の時でも選択

379:デフォルトの名無しさん
19/10/05 17:18:56.47 NXndjuW4.net
一応以下のような感じになった。Thx!
URLリンク(coliru.stacked-crooked.com)

380:デフォルトの名無しさん
19/10/05 17:19:54.63 NXndjuW4.net
URLリンク(coliru.stacked-crooked.com)
こっちだった。Orz
んじゃ。

381:デフォルトの名無しさん
19/10/05 17:28:26.58 QHD8CUaF.net
>>377
1. constexprにしてもいいんじゃない?
2. 出力関数作成しよう
template<typename Char>
std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, const Fraction& frac){
return os << frac.GetNumerator() <<'/'<<frac.GetDenominator();
}

382:デフォルトの名無しさん
19/10/05 19:08:43.36 NXndjuW4.net
>>378
1.できなくはない。機械的に接頭語つけるだけでいいよね。
2.暇だから作るわ。
行ってきまーす。

383:デフォルトの名無しさん
19/10/05 19:46:54.47 NXndjuW4.net
URLリンク(ideone.com)
ただいまー。イデオンで動かせるようにした。Gcdがバグってないといいなぁ。
あとvc2019では意味不明なエラーで動かない。

384:デフォルトの名無しさん
19/10/05 19:58:28.51 NXndjuW4.net
フィードバックハブに投げておいた。

385:デフォルトの名無しさん
19/10/06 10:28:58.03 yc9LKsYB.net
>>380
マルチ禁止

386:デフォルトの名無しさん
19/10/06 13:42:53.69 bPt7YQEe.net
>>382
ソーリー。

387:デフォルトの名無しさん
19/10/07 19:17:43.20 PHxdOQnu.net
C++ってなんでヘッダファイルいるんですか
最近マシン早いんだし
全部ソースに書いてインポートすればいいのに

388:デフォルトの名無しさん
19/10/07 19:38:58.27 Xs+XlBV4.net
やれば?(クレヨンしんちゃん風に)

389:デフォルトの名無しさん
19/10/07 19:52:54.51 9pxPpXZa.net
来年まで待ってね

390:デフォルトの名無しさん
19/10/07 20:58:42.59 A3KSW75p.net
>>384
むしろソースがいらなくて全部ヘッダに書けばいい
inline変数とかもできるようになったことだし

391:デフォルトの名無しさん
19/10/07 21:05:07.29 8FnUNDHt.net
>>387
たまに趣味で何でもかんでもtemplateでゴリゴリ実装してるとガチでそれになるww

392:デフォルトの名無しさん
19/10/07 21:26:10.24 YMM6HSZT.net
>>385
ヤレばデキるは魔法の言葉

393:デフォルトの名無しさん
19/10/08 09:06:39.07 xr4jQIWZ.net
プリコンパイルヘッダーって使ってます?
使っているプロジェクト見たことないですわ。

394:デフォルトの名無しさん
19/10/08 20:03:58.69 kGAGzuS0.net
>>387
こういう馬鹿野郎が出てくるからメタプロとかテンプレ好き連中ってのは嫌いなんだよ。

395:デフォルトの名無しさん
19/10/08 21:04:41.31 OCfPMe68.net
C++なんて趣味でやってるんだからテンプレ好きでもええやん

396:デフォルトの名無しさん
19/10/08 21:16:41.69 /kdim2Vo.net
出てくることの何が嫌なんだろうか
はっきり言って病気だ

397:デフォルトの名無しさん
19/10/08 21:42:59.95 lGNioH0G.net
headerオンリーってのは可搬性に優れた良いものだろ
特にテンプレート多用している奴は、一部関数だけソースファイル分離する意味が薄い

398:デフォルトの名無しさん
19/10/08 21:43:38.32 asJ1ctJB.net
>>391
どんなものにだって馬鹿は出てくるだろうに

399:デフォルトの名無しさん
19/10/08 21:54:07.26 J87hrB1p.net
「全部ヘッダ」と言われると、そのときの「ヘッダ」の定義がどういうものなのか気になる。

400:デフォルトの名無しさん
19/10/08 21:57:19.52 EwyBASw5.net
趣味でやってる人は全部ヘッダでいいと思う

401:デフォルトの名無しさん
19/10/08 22:09:52.63 tSj7di+z.net
>>390
VCのやつは使いまくり
依存するライブラリのヘッダファイルを標準のやつもソリューション内のやつも全部まとめて
stdafx.hの中でインクルードしたらことのほか便利
ただし同じプロジェクトのヘッダファイルを入れだしたら目的を見失って氏ぬ

402:デフォルトの名無しさん
19/10/08 22:10:50.35 hpLG4xMo.net
テンプレート関数は便利だしconstexpr関数は市民の義務だし
結局ほとんどヘッダファイルに書くことになるでしょ

403:デフォルトの名無しさん
19/10/08 22:30:34.35 X4FGjRpd.net
初心者ですが質問させてください
print(1, 3.14, "abc");とやると引数の中身を順番にスペース区切りで出力してくれるような関数は
可変引数テンプレートの再帰呼出しを使うと便利にできることを知りました。
そこで引数の型に応じて出力の見た目を少し変えたいのですが、
関数の特殊化をすればいいですか?
typeidだと動的な評価になってしまうんですよね?

404:デフォルトの名無しさん
19/10/08 22:33:59.15 kGAGzuS0.net
予想通りの馬鹿回答で笑ってしまった。
やっぱいい判別になるわテンプレバカ。

405:蟻人間
19/10/08 22:37:33.87 jfG+k1ni.net
>>400
引数一つに対するテンプレート関数を作って特殊化してそれに少しずつ渡せばできるよ。

406:デフォルトの名無しさん
19/10/08 22:42:38.66 /kdim2Vo.net
C++嫌いなのにいつまで居座るんだろうなこのガイジ

407:デフォルトの名無しさん
19/10/08 22:57:34.25 HxNAD6ah.net
好き嫌いの問題じゃねーんだわ

408:デフォルトの名無しさん
19/10/08 23:04:05.43 /kdim2Vo.net
こんな雑談スレ好きな奴以外に需要ないだろ
こんな辺境別に見なくて良いんだよ?

409:デフォルトの名無しさん
19/10/08 23:08:13.69 hpLG4xMo.net
>>400
c++17以降ならif constexprとstd::is_same_vの使用を検討してみるのもいいかも

410:デフォルトの名無しさん
19/10/09 04:08:22.18 NmoqHfbB.net
400です。頑張ってみましたがどうにもコンパイルエラーが出ます
難しいですねC++は...
void print() {}
template<class... Args>
void print(const char* c, Args... args) {
cout << "[" << c << "]" << endl;
print(args...);
}
template<class First, class... Args>
void print(First first, Args... args) {
cout << first << endl;
print(args...);
}
int main() {
print(1, 3.14, "abc");
return 0;
}

411:デフォルトの名無しさん
19/10/09 04:17:51.46 NmoqHfbB.net
あ、こういうふうにするとコンパイルできました。引数2個の関数を特殊化したからエラーになった?
テンプレートの展開のされ方がよくわからないけど、とりあえず目的のことはできました
ありがとうございました
void print(const char* c) {
cout << "[" << c << "]" << endl;
}
template<class T>
void print(T t) {
cout << t << endl;
}
template<class First, class... Args>
void print(First first, Args... args) {
print(first);
print(args...);
}

412:デフォルトの名無しさん
19/10/09 04:21:52.30 NmoqHfbB.net
>>406
いわゆる型特性というやつでしょうか?enable_ifを使うのかと思い試したもののうまくいかず、
ネットで調べるとenable_ifと可変引数テンプレートは相性が悪いという意見を見つけたり...

413:デフォルトの名無しさん
19/10/09 07:02:07.47 8qv563yz.net
>>409
if constexprを使った例はこんな感じ
template<class First, class... Args>
void print(First first, Args... args) {
if constexpr(std::is_same_v<First, const char*>){
std::cout << "[" << first << "]" << std::endl;
} else {
std::cout << first << std::endl;
}
if constexpr(sizeof...(args)>0){
print(args...);
}
}

414:デフォルトの名無しさん
19/10/09 10:59:59.89 RbUf+g7C.net
const char * 自体も class First や class Args と一致するんじゃね

415:デフォルトの名無しさん
19/10/09 21:59:58.44 8qv563yz.net
First と Argsの二つがあるのがややこしい場合は畳み込み式でもできるぞ
template<class... Args>
void print(Args... args){
  ([](auto t){
    if constexpr(std::is_same_v<decltype(t), const char*>){
      std::cout << "[" << t << "]" << std::endl;
    } else {
      std::cout << t << std::endl;
    }
  }(args), ...);
}

416:デフォルトの名無しさん
19/10/09 22:42:32.58 J+0BhmRu.net
win系のOSの画面に1.txt~5.txtがあります。1.txtと2.txtをドラッグして選択したとします。
この状態で3.txt~5.txtを選択したことにするにはどのようなコードを書けば良いですか?

417:蟻人間
19/10/09 22:52:59.82 bPxMjWa1.net
>>413
ListView_SetItemState

418:デフォルトの名無しさん
19/10/10 00:29:05.87 uUO69neG.net
エクスプローラにdll注入とか?

419:蟻人間
19/10/10 01:32:41.34 VnnXeZwz.net
前にやったことがある。
URLリンク(github.com)

420:デフォルトの名無しさん
19/10/11 01:40:25.90 n351RXRL.net
std::shared_ptrを構築後に(カスタム)デリータを変更するのは無理?
既にどっかで作成済みのshared_ptrについて、破棄タイミングを後から見れないかなと

421:デフォルトの名無しさん
19/10/11 02:44:16.61 uKeO6WuZ.net
別のstd::shared_ptrをカスタムデリータ付きで構築してswapすれば

422:デフォルトの名無しさん
19/10/11 04:06:16.56 RvdWaBLb.net
shared_ptrとunique_ptrでdeleterの指定方法が違うってのが興味深いね。

423:デフォルトの名無しさん
19/10/11 12:29:56.77 w5dDNHMJ.net
VCのlatestでchar8_tが入ってたわ
やっとC++erが文字コード問題から解放されるんだな

424:デフォルトの名無しさん
19/10/11 14:00:32.34 XWYiG0pn.net
やったぜ。

425:デフォルトの名無しさん
19/10/11 15:19:50.16 iqVlf+4W.net
>>418
デリータごとswapされたわ
stackoverflowにも似たような質問があったけど結論としては出来ないっぽい
たぶん

426:デフォルトの名無しさん
19/10/11 23:12:48.13 WXWRLB/C.net
>>392
別にテンプレ好きでも構わんが、C++ユーザー全員が趣味だと思ってんの?

427:デフォルトの名無しさん
19/10/11 23:15:04.89 WXWRLB/C.net
>>405
雑談以外に役に立つ書き込み出来なくてすみません、ってことか

428:
19/10/12 08:08:31 vgsPsMOm.net
>>423
C++ユーザが全員趣味なんてどこにも書いてないし、あるプログラミング言語が趣味でしか使われてない状況なら、委員会なんていらないわwww

429:
19/10/12 08:48:46 fl5cgmi7.net
衣食住の確保以外の仕事なんてみんな趣味みたいなもんだよ
なくたって構わんのだから

430:
19/10/12 08:58:25 rY+KRAa3.net
農業以外は遊びってことか!

431:デフォルトの名無しさん
19/10/12 09:03:04.22 tzOo7sle.net
原始人から見たら1次産業以外は遊びだしそうだろ

432:デフォルトの名無しさん
19/10/12 09:06:03.19 w6XAfbR5.net
委員会なんて何の役にもたってねーだろ。
構文解析もまともに理解できてないバカが俺様仕様の理想に突っ走ってるだけのクソ組織で、
仕様の実装、デバッグの手間なんてこれっぽっちも考えてないのがよくわかる。

433:デフォルトの名無しさん
19/10/12 09:14:16.17 Fi90LVHu.net
デバッグできねえのを人のせいにするクズがよく言うぜ

434:
19/10/12 09:54:19 DT43rpFP.net
近年は新機能は三大コンパイラ(GCC,MSVC,Clang)での試験実装が入ってから仕様入りするのが普通になってるし
コンセプトなんてまさにデバッグの手間の軽減を第一目的に苦心して作られた機能なんだけど
どのへんを見てよくわかったのか教えて

435:
19/10/12 10:00:51 w6XAfbR5.net
>>431
実装したことないやつは黙っててね。
で、そのコンセプトを実際のコードでコンパイルした時間がどれくらいになるかわかってる?
そういう有用なベンチマークもほとんど出さずに無理やり入れようとするから
信頼を無くしてるんだよ。

436:
19/10/12 10:19:47 Nq/Z/R6A.net
経験したことは全て正しいっていう日本特有のアホ理論だろそれ
経験してないお前に発言権は無い、っていう
その理屈を持ち出すヤツは大抵はアホ

437:
19/10/12 10:24:58 69fBrMS4.net
コンパイル時間は、コンパイラの出力する最適化されたバイナリの実行速度に比べたら問題ではないだろ

しかも構文解析にかかる時間なんて最適化時間に比べりゃ屁みたいなもの

438:
19/10/12 10:26:15 mYzO26Pi.net
似たようなものを複数書いてもバグ修正時に一部見落としなんて馬鹿げたことになるわけで
マクロでもテンプレートでもまとめられるものはまとめたほうがいいわな

439:
19/10/12 10:27:43 69fBrMS4.net
c++言語の場合、パースのコンテキスト依存が、識別子の種類でも変わるから、テンプレート時の記述でtypename やらtemplateやらで、識別子の種類自体を指定する羽目になっているのはあるよね

440:
19/10/12 11:23:13 zNYGVDyE.net
>>434
テンプレートふんだんに使ったライブラリ実用してるとひどいことにはなる
アプリ自体は数万行なのにコンパイル10分以上とか

441:デフォルトの名無しさん
19/10/12 11:27:59.19 KmpqQhzT.net
>>432
お前が信用しないのは勝手だが、みんなの総意みたいに言うなよ

442:
19/10/12 12:09:52 73DoxmjF.net
数万行で10分が早いのか遅いのかよくわからない

443:デフォルトの名無しさん
19/10/12 12:15:22.09 69fBrMS4.net
それは本当にパースの複雑さのせいなのかは疑問だな
templateだと、プログラマは簡単にコンパイラの仕事をあまり意図せず増やしてしまいがちだからね。
std visitで引数増やすとコンパイル時間は簡単に増やせるよ。
5つくらいでもうコンパイラが落ちたりする
やらせていることの面倒くささ、それを手書きすることを考えれば妥当なのだけど

444:
19/10/12 12:41:57 Tqr7IA/6.net
最近C++触ってないけど数万程度で10分もかかるの?
10万行程度なら5分以内に終わってほしいところだけど…

445:
19/10/12 13:13:02 trzfpzAc.net
>>439
かなり遅いです。
ヘッダファイル *.h とソース本体のファイル *.c では事情が違いますが、
OSのバージョンによりますが、Win32の標準ヘッダファイルの windows.h などだけでも
コメントを除外しても2万行弱くらいあります。
これのパースは、VC++で1秒~数秒くらいです。
通常は、precompiled header を使うので、一つのプロジェクトで一度だけ
パースされることが多いです。
ただし、プロトタイプ宣言やマクロ定義、構造体定義、inline関数定義
などだけで、実際のコード生成は伴わないので、*.c の数万行とは
また事情が違います。*.c はコード生成を伴うので、同じ行数であれば*.hよりも
遅くなる傾向があります。
しかし、それでも、C++98 の場合、数万行だと3秒~10秒以下でコンパイルできます。

446:デフォルトの名無しさん
19/10/12 13:23:47.19 UpKv7BB3.net
↑こいつはVSスレで有名なキチガイなので放置で

447:デフォルトの名無しさん
19/10/12 13:24:45.74 69fBrMS4.net
c++の文法のせいでパースが遅いってレベルの話じゃないような

448:デフォルトの名無しさん
19/10/12 15:33:32.46 UCFxfzGx.net
ヘッダオンリーのライブラリがポータブルとか言われてもてはやされるのがc++だからね
生産性の意識が間違った方向に向いてる
コンセプトでどうなることやら

449:
19/10/12 15:52:13 K75UXpIa.net
俺の10万行程度のアプリは1分以内にコンパイル終わるが・・・
10分てどこの世界だ

450:
19/10/12 19:26:26 8VsKOlOD.net
「参照の配列」を作りたいときって現状 reference_wrapper を使う以外ないですか?

451:デフォルトの名無しさん
19/10/12 20:29:07.16 iehpkqJW.net
ポインタやスマポじゃいかんのか

452:
19/10/12 20:55:57 cS98TRHZ.net
>>437
プリコンパイルヘッダー使え…!

>>446
VC++2010の場合配列要素のアドレスの配列というのを
それぞれ1万行ぐらい書いてリリースビルドすると10分かかる

453:デフォルトの名無しさん
19/10/12 23:18:34.83 zNYGVDyE.net
spiritで構文解析させてたコード(その上et使った自作ライブラリあり)だから�


454:痰ニして極端だったかもしれんけどね プリコンパイルドヘッダは使ってたよ 効いてるときは数分かからなかったと思う というか5年以上そのコード使ってないんで今のマシンならまだマシになるとは思う



455:デフォルトの名無しさん
19/10/13 01:04:01.79 2Ilco01g.net
boostを多用した10数万行のソースでprecompileありでreleaseビルドしたら10分くらいかかってたけど、debugビルドでは1,2分くらいだった気がする。パースだけなら大したことないけど最適化がかなり遅いと思われる。

456:デフォルトの名無しさん
19/10/13 01:06:42.02 uORMYh+w.net
翻訳単位が増えると単純に遅くなるし
リンク時最適化でもさらに遅くなる

457:
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
このヘッダは頭がおかしい


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