X



C++相談室 part133

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (ワッチョイ 1fcf-H1rY)
垢版 |
2017/11/24(金) 16:52:50.43ID:WoNXR2ax0
次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512

C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

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

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

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

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
0131デフォルトの名無しさん (ワッチョイ 47b3-h3cN)
垢版 |
2017/11/28(火) 11:27:26.73ID:QyLugM0S0
Javaはいいぞう〜。
0133デフォルトの名無しさん (ワッチョイ 47b3-h3cN)
垢版 |
2017/11/28(火) 20:00:44.77ID:w5+ReiF20
煽っても無駄ですよ!
0135デフォルトの名無しさん (ワッチョイ 0778-4Z1+)
垢版 |
2017/11/28(火) 20:33:55.36ID:HaaNvQJm0
俺、D言語の方が好きなんだ
0137デフォルトの名無しさん (スプッッ Sdff-T4vC)
垢版 |
2017/11/28(火) 20:56:09.01ID:VZsT4wzqd
pairを戻り値とする関数内でmake_pairを返そうとしてる

pair<string, string>( vector<string> vec)
{
return make_pair<string,string>(vec[0],vec[1])
}

要素数が2より小さいときにペアが作れないから他のものを返したいのだけど
こういう場合は何を返せば良いのだろうか?
受けてる先では

map<string,string>にinsertをしてる
0140デフォルトの名無しさん (ワッチョイ c780-U9VW)
垢版 |
2017/11/28(火) 21:16:00.33ID:RUZbaLWb0
>>137
しらんがな。返したいもの返せよ
0145デフォルトの名無しさん (ワッチョイ 7f6e-Mqmq)
垢版 |
2017/11/28(火) 22:45:01.20ID:VD3vPh0F0
>>137
何を返しても嘘になるので、返してはダメ
if (vec.size() < 2) throw logic_error{"runt vector"};
0146デフォルトの名無しさん (ワッチョイ 7f6e-Mqmq)
垢版 |
2017/11/28(火) 22:46:39.17ID:VD3vPh0F0
もしくはassert(vec.size() >= 2);
0147デフォルトの名無しさん (ワッチョイ 0778-4Z1+)
垢版 |
2017/11/28(火) 22:54:08.70ID:HaaNvQJm0
name=valueみたいなのを分割してmapに入れる感じ?
俺も例外投げて止めてしまった方がいいねと思うね
0148デフォルトの名無しさん (ワッチョイ 47b3-h3cN)
垢版 |
2017/11/28(火) 23:41:38.36ID:w5+ReiF20
だが待ってほしい。
例外を投げるということは誰かに責任を押し付けることではないだろうか。
0150デフォルトの名無しさん (ワッチョイ 079f-5mWG)
垢版 |
2017/11/28(火) 23:53:44.75ID:S7QzL+/B0
>>129
C++より簡単でお気軽な言語が大量にある今、C++で全くの初心者用の環境を要求すること自体が間違い。
それはトレーラやユンボでド初心者を教習するのに近い。
そうではなく、まず普免を取ってからこれらの特殊車両だろ。
お前は「俺はトレーラー乗りになりたいから、最初からトレーラーでやってくれ」とゴネている教習生なんだよ。

C++のオブジェクト指向でいい本が「世界中に」ない=C++やるような奴にはそんなもの需要がない

でしかない。お前はそれすら理解出来ない馬鹿なのに、

> C++の本を書くような人はオブジェクト指向の説明をするのは沽券に関わると思っているのか、
> あるいは「C++の専門家」にはオブジェクト指向を教える能力がないのか。

ってのは自意識過剰すぎる。世界はお前を中心に回っているわけではない。
C++を使う必要がある局面でC++を使う人たちには、今更オブジェクト指向なんて教える必要がないんだよ。
それは自明だから。
そして本を書いている奴らも別段崇高な精神を持って布教しようとしているわけでもない。
いや、そういう奴もいるかもしれないが、当然「売れるから書く」という下俗な奴も世界には必ず居るはずであり、
そういう奴らすらいない=売れない=需要がない=みんな既に知っているから、でしかない。
だいたい、オブジェクト指向ってのはプログラミング手法であり、
言語とは別の軸なのだから、「『C++の専門家には』オブジェクト指向を」ってのも論理的におかしい。
0151デフォルトの名無しさん (ワッチョイ 079f-5mWG)
垢版 |
2017/11/28(火) 23:54:34.49ID:S7QzL+/B0
そもそもオブジェクト指向がさも特別で崇高な存在だ、なんてのはJava教団がそうしたがっているだけで、
実際のところは、Cで大規模コードを扱うと、最初はstruct*、次に関数ポインタの嵐になり、
これらをどうにかしてコンパイラに自動的にやらせよう、として生まれたのがC++のオブジェクト指向だ。
だから既に言ったがC→オブジェクト指向は完全に地続きなんだよ。
これは出自からしても当然で、
Cの典型的な問題点を新たな言語サポートにより解決することを目指したものがC++だから。
逆に言えば、C++98で搭載されている機能はほぼ全てCの問題点の克服であり、
Cを使いこなしていた連中にとっては当たり前に「その気持ちは分かる」ものでしかない。(なお同意するかは別)
そしてオブジェクト指向もこの中に入っている。
だから当初からオブジェクト指向の有効性をわざわざC++で語る意味はなかったし、
他お手軽系言語が乱立している現在、さらに輪をかけてその必要性がなくなっている。
0152デフォルトの名無しさん (ワッチョイ 079f-5mWG)
垢版 |
2017/11/28(火) 23:55:33.62ID:S7QzL+/B0
それでも初心者が「オブジェクト指向自体を学びたい」ときにはどうすればいいかと言えば、
俺個人は「まず3k行程度なら平気で書けるようになってからでいい。そうすればおのずと分かる」という立場だ。
しかしそれでもHellowWorld直後のド初心者に教えようってのならJava教団みたいに洗脳していくしかない。
どう見ても実行に直接関係ない記述の嵐であり、ド初心者にとっては「無駄じゃね?」としか見えないだろうし。

だからこの意味ではJava教に入信しろ、というのもありではあるのだが、
問題はJava教団はJava教の不備は絶対に認めないというか、気づいてないことだ。
関数ポインタさえあれば非常に単純に実装できることを、無理に継承を導入したおかしな構造で対応し、
しかもそれをデザインパターン(キリッと公式化しようとしている所が滑稽だ。
しかし、Java教信者は関数ポインタの存在を知らないから、この教義がおかしいとも気づけない。
また、Javaのオブジェクト指向は今既に邪道で、オブジェクト指向するのが目的化してきてる。
例えばprivateにすること、イテレータを実装することが目的になってるだろ。
だから実際に前スレ896みたいな事も平気でやる。本当に全く意味が無い。
(これについてはLinusはC++erも同様だと言っているが)
だからJava教でオブジェクト指向を学ぶのは、邪教というか、
邪オブジェクト指向を学ばされる可能性がかなり高いのでオススメしない。
0153デフォルトの名無しさん (ワッチョイ 079f-5mWG)
垢版 |
2017/11/28(火) 23:56:37.90ID:S7QzL+/B0
結局、オブジェクト指向は「学ぶ」物ではなく、本来は「悟る」物なんだよ。
そしてそれは涅槃の境地で解脱しろ、みたいな崇高なものではまったくなく、
「この交差点、信号無いと危なくね?」位の、普通に運転してりゃ分かるだろ、程度の物でしかない。
だからわざわざ解説するほどのことでもないんだが、結果的に、
「オブジェクト指向しろ」と言われる割には解説本がなく、初心者にとってはなんだかよく分からん状況になっている。
そしてお前みたいな馬鹿は「幼稚園で『どこに信号を立てるべきか』きっちり教えるべきだ!
俺は教わっていないから分からない!教えられる先生もいないのか!」
と主張するわけだが、完全にモンペ通り越してキチガイだろ。
オブジェクト指向は幼稚園で教えるべき内容ではないし、教えなくとも自然と理解できる物だし、C++は幼稚園ではないし。

そして脱線すると、「結局オブジェクト指向はよく分からんね」というゆとりが逃げ出した結果が関数型祭りだ。
いや結果的にはC++/C#/Javaの全てがラムダを導入したのだから、一定の成功を得た、と評すべきかもしれんが。
しかしErlangみたいに「オブジェクト指向での限界を突破する」為の明確な方策がなく、
単に馬鹿な連中がより簡単な関数型に逃げ出しただけであり、そこで何か新しい境地が拓けるものではなかった。
そしてGoも俺はこれに似た匂いを感じてる。C++出来ないゆとりが集まっただけじゃんこれ、みたいな。
ただし、確かにC++は無駄に複雑化しているのも事実だが。

> Java鹿
それ、読み方は「Ja馬鹿」ね。ただ表記上分かりやすいので「Java鹿」にしてるが。
0157デフォルトの名無しさん (ワッチョイ 079f-5mWG)
垢版 |
2017/11/29(水) 00:05:12.43ID:LrQLLGRZ0
まあ俺はゆとりは死ねとしか思って無いからな。
つか、この程度の文も読めないのなら、お前ら仕様書や本も読めないだろ。
向いて無いからプログラマ辞めろよ。
0158デフォルトの名無しさん (ワッチョイ 7fa5-5mWG)
垢版 |
2017/11/29(水) 00:13:55.97ID:jItlzFQF0
>>148
そこはまぁその関数の仕様として、呼び出す側が確実にcatchする責任があるわけだな。
それを忘れると例外が呼び出し階層を突き抜けていっちゃう。
そういう事態を防ぐために考えられたのが検査例外だけど、これはこれで使いづらい面があるんで
Java以外にはあまり採用されなかった。
そんなことを考えてみると>>137程度の目的で例外などという暴力的な仕組みを使うのがそもそも
適切なのかどうか。Goの選択もそういうことなんだろう。
0159デフォルトの名無しさん (ワッチョイ 47b3-lrN+)
垢版 |
2017/11/29(水) 00:19:11.17ID:gRQoJ5CS0
ttp://nekko1119.hatenablog.com/entry/20120625/1340602468

main関数の最後にあるstringへのキャストでエラーがでるのですがなぜですか。
エラー C2440 '型キャスト': 'Any' から 'std::string' に変換できません。

コンパイラはvc++2017です。
0162デフォルトの名無しさん (ワッチョイ 47b3-lrN+)
垢版 |
2017/11/29(水) 00:36:37.38ID:gRQoJ5CS0
>>161
通す方法ではなくてなぜ通らないのかが聞きたいのですが

template<Type>
operator Type()
で暗黙の型変換のオーバーロードを定義しており、
int型やHoge型に対して代入する際にそれが使われているのに
std::stringに対してだけうまくいかない理由はなぜかが知りたいです。
0165デフォルトの名無しさん (ワッチョイ 5fe7-8Ex9)
垢版 |
2017/11/29(水) 00:51:28.18ID:AJHdDibY0
>>162
gcc 7.1.0とclang 6.0.0では通った
ただしstd::type_infoと書くべきところをただtype_infoと書いてる個所があるので、それは直したけど。
それより下のコンパイラバージョンだとエラーになった。(ambiguous conversion)

そして
(string)val
の代わりに
(const string&)val
と書いたらclang 4.0.1でも通った。
0166デフォルトの名無しさん (ワッチョイ 47b3-lrN+)
垢版 |
2017/11/29(水) 01:02:17.23ID:gRQoJ5CS0
(int)valはいけますけど
(Hoge)val, (std;;string)valはダメのようですね。

で、ご指摘のとおり
(Hoge&)val, (std::string&)valは通りました。

前者と後者の違いは分からないですが。
0167デフォルトの名無しさん (ワッチョイ 7f80-xsLR)
垢版 |
2017/11/29(水) 01:27:40.52ID:/RfTzpPk0
& の意味が分からないなら、プログラミングできない

(int)val
普通、こういうキャストの書き方は、しない

static_cast など数種類あるキャストの書き方の中から、
キャストの種類を指定してキャストする

君は、入門書を読んでいないだろ
0168デフォルトの名無しさん (ワッチョイ c780-U9VW)
垢版 |
2017/11/29(水) 02:04:04.04ID:qCLwkY6K0
>>143
newの代わりにmalloc使ってるとか思ってるアホ?
今時new使うやつは以下のどれか
* Javaから来たC++初心者
* 化石コンパイラ使わさせられてる可哀想なやつ
* 自身が化石な可哀想なやつ
* パフォーマンスのために用意されてない構造の実装が必要なライブラリ設計者

お前は1番目と3番目の複合型だろうね。
0169デフォルトの名無しさん (ワッチョイ 47b3-lrN+)
垢版 |
2017/11/29(水) 02:17:56.38ID:gRQoJ5CS0
template<class Type> Any::operator Type() const

上をやめて、下の2つを定義したらmain関数の記述そのままでうまくいきました。

template<class Type> Any::operator Type&() const
template<class Type> Any::operator const Type&() const

理由は分からないです。分かる方がいたら教えてください。
0171デフォルトの名無しさん (ワッチョイ a723-SHUC)
垢版 |
2017/11/29(水) 03:06:58.25ID:l2Be3tXA0
質問の意味わからんでレスしてる奴うざいわ
0172デフォルトの名無しさん (スプッッ Sdff-T4vC)
垢版 |
2017/11/29(水) 04:38:58.34ID:llo+D0tpd
>>144
>>139
>>145
基本的には2以下は存在しないから例外処理組み込もうと思ったけどnullobjectってのがあるのね
おそらく俺の理想的にはこいつが適してそうだからこいつを調べてみるよ

>>145の言うとおりに絶対に呼ばれないキーをいれておくのも検討違いな気はしてる
0173デフォルトの名無しさん (スプッッ Sdff-T4vC)
垢版 |
2017/11/29(水) 04:50:10.36ID:llo+D0tpd
>>147
まさにそれをしようとしてる
そこのロジック的には空文字入れる予定だから必ず2以上になるのだけど
関数分割していて関数としては何が返ってくるか不明なため
問題が起きたときのコードを記載しようとしてる
vectorのsizeが0や1の時にアクセス違反になってしまうからどうやれば回避できるのかなぁと悩んでる

例としてはこんなん
=value
key=value
key=
==value
0174デフォルトの名無しさん (スップ Sd7f-cUxe)
垢版 |
2017/11/29(水) 07:52:20.02ID:o9GGe8w4d
>>171
確かにそうだね
それにclangの最新だと通ることから、それなりにややこしい話かと思う
0175デフォルトの名無しさん (ドコグロ MMdb-CDhT)
垢版 |
2017/11/29(水) 08:27:09.91ID:WoWbjmOBM
>>173
> key=value
これは正常ケースだよね

> key=
仕様によるけどvalueに空文字入れときゃいいんじゃね?

> =value
> ==value
エラーでしょ?
例外発生させるなり、ログ採ってnullptr返すなりしなよ
そんなものを無理矢理 map に突っ込もうとするのがおかしいと思うぞ
0176デフォルトの名無しさん (ワッチョイ 0778-4Z1+)
垢版 |
2017/11/29(水) 08:58:03.16ID:p7HSt6hG0
>vectorのsizeが0や1の時にアクセス違反になってしまうからどうやれば回避できるのかなぁと悩んでる
vectorの要素数が不確定の場合はatで取り出せばいいよ、なんかあったらout_of_rangeが飛んでくるから
0177デフォルトの名無しさん (スプッッ Sdff-T4vC)
垢版 |
2017/11/29(水) 09:33:07.40ID:llo+D0tpd
>>175
空文字入れるのはできてる
ただベクターの生成は別関数が行うから引数に渡されるベクターにいくつ値が入っているか不明
だからマップ作成側で個数を意識する対策する必要あるよね?って話
ベクターの生成に関しては実際問題ない

>>176
try catchするしかないのかな
nullopt返そうとしたけど実装無理だったわ...
0178デフォルトの名無しさん (ワッチョイ 8746-TjkM)
垢版 |
2017/11/29(水) 10:42:28.73ID:IulhJnoW0
例外投げるかなにかしとけばよいって
ロジック的に要素数2未満はあり得ないし想定してないんでしょ?
余計なことする必要ないって、以降の処理が余計ややこしくなるだけだから
エラー処理が適切
0182デフォルトの名無しさん (ワンミングク MM3f-U9VW)
垢版 |
2017/11/29(水) 11:28:13.62ID:CqyTJd2aM
>>178
おいおい、例外をエラー処理以外に何に使うってんだよ
0183デフォルトの名無しさん (ワッチョイ 47b3-h3cN)
垢版 |
2017/11/29(水) 11:33:09.98ID:51eC79nG0
メッセージの通知に!
0184デフォルトの名無しさん (ワッチョイ 8746-TjkM)
垢版 |
2017/11/29(水) 12:07:51.67ID:IulhJnoW0
>>182
だから、エラー処理が適切だから
例外投げてエラー処理でもしとけば?と書いてあるはずだが・・・

ただこの手合い、例外投げて、それを受け取ったからと言って
リカバリーしてプログラムを再開できるかはわからないよなぁ
プログラム本体の状態を一切汚さずに(書き込まずに)
新規領域のみで何か処理をして
例外が飛んで来たら全てを無かったことにする・・・とか
例外でやる場合は例外安全を確保するのが結構面倒なんで
プログラムの末端から例外投げるのは最後の手段にしたい

だから「実際に実行してみないとエラーが出るかわからない」系のエラーが無いのであれば
早期の段階で入力データにエラーがあるかどうか精査して、エラーがあればその旨返して
以降はエラーが発生しない前提で処理する(ので巻き戻すことは考えない)
もし不慮のエラーが発生したら、バグであるからログ吐いて異常終了
可能なかぎり、なるべくこちらで行きたいわけで
0185139 (ワッチョイ 272d-eGxq)
垢版 |
2017/11/29(水) 12:10:47.10ID:/Yd3ZvxU0
>>177
optionalを挙げたものだけど 惑わせたようで申し訳ない

insert 前にチェックして不正ならそもそもinsertしない設計を考えてました
結局 optionalを返す insert / find を自前実装することになるから
そんな面倒な事せずに 素直にXXXで例外投げても全く構わないと思う

一応詫び代わりに書いてみたけど 鵜呑みにはしないでください
C++17 例外なし 読みやすさのためにautoなし
https://wandbox.org/permlink/rag4d7YPqwPKQpNq
0186デフォルトの名無しさん (ワッチョイ 7f6e-Mqmq)
垢版 |
2017/11/29(水) 12:13:09.20ID:f8CPZ7/S0
182=184
同じ臭いがする
0187デフォルトの名無しさん (スップ Sd7f-cUxe)
垢版 |
2017/11/29(水) 12:14:34.01ID:o9GGe8w4d
検査可能な事前条件はそりゃ呼び出し側の責務にしたいわな
0188デフォルトの名無しさん (ドコグロ MMdb-CDhT)
垢版 |
2017/11/29(水) 12:52:35.24ID:WoWbjmOBM
>>177
> ただベクターの生成は別関数が行うから引数に渡されるベクターにいくつ値が入っているか不明
.size で取ればいいだけだろ
そもそも name=value のパース結果をベクターで渡してくると言うの設計もどうかと思うが

> だからマップ作成側で個数を意識する対策する必要あるよね?って話
そうだよ、その対策を>>175にかいたつもりだが...
もしかして
name=

=value
の両方とも vec[0] にしか入れてこないとかなってるんじゃないよね?
だとしたら生成部分を直さないとどうしようもないけど
0189デフォルトの名無しさん (ワッチョイ 47b3-h3cN)
垢版 |
2017/11/29(水) 13:49:04.14ID:51eC79nG0
ヴェクターノズル搭載。
0190デフォルトの名無しさん (スプッッ Sdff-T4vC)
垢版 |
2017/11/29(水) 14:47:34.47ID:llo+D0tpd
色々とありがとう
最終的には呼び出しもとでtrycatchすることにしました

>>188
両方とも0 1の要素に値いれてるね


もう一個別件なのだけど
ファイルの存在チェックとファイルのオープンエラーについて教えてほしい

ある設定値は特定の設定ファイルが存在するにも関わらず読み込めなかったときに有効になるものとしたい
且つ設定ファイルが存在しないときもある
(設定する値が二つある。ひとつはkey=valueの形のvalue、もう1つは正常にファイルから値がとれたか否か)

ファイルが存在しないときはvalueの値をデフォルトで扱う必要があるので、
単純にファイルオープン処理を用いて一度で処理できなかった
(ファイルがなくて開けないのか、あって壊れていて開けないのか判断できないので)

そのため
statでファイル存在有無チェック→ファイルオープンとしたのだけど
タイミングが一致してないので刹那のタイミングでのファイル焼失を担保できないと言われている
どうすればファイルがなくて開けないのか、ファイルが壊れていて開けないのかを判断できますか
0192デフォルトの名無しさん (ワンミングク MM3f-U9VW)
垢版 |
2017/11/29(水) 15:30:10.25ID:CqyTJd2aM
keyにデフォルト値が存在するなら、最初にデフォルト値のmapを持つ。
ファイルを読み込んで存在したキーだけ上書き更新する。
だけでいいだろ。ファイル読み込まれなければ全部デフォルト値のままだ。
0194デフォルトの名無しさん (ワッチョイ 079f-5mWG)
垢版 |
2017/11/29(水) 20:17:29.87ID:LrQLLGRZ0
>>168
ゆとり死ね
お前は何も分かってないし、学ぶ知能もない


>>190
> 刹那のタイミングでのファイル焼失を担保できないと言われている
てかそいつに聞けよ。

課題として与えられてるのなら、そいつは「考えさせることに意味がある」と思っているのだから、
こんな糞上司に付き合ってられるか、と思ってないのなら自分で考えろよ。
ここで聞いているのは宿題の答えだけ写しているようなもので、全く上達しないぞ。
0200デフォルトの名無しさん (ワッチョイ 8746-TjkM)
垢版 |
2017/11/29(水) 22:29:25.62ID:IulhJnoW0
割とタイムリーな話題というか、ここ一週間ぐらい、実行時エラーやら例外やらが発生したとき
どうやったらプログラムを安全に再開するか考えてた
で、至った考えは、ひとまとまりの一連の処理を二つに分割して
まず前半はread onlyセクションで、プログラム本体の状態を書き換えてはならないが
そのかわり例外が発生したら、無かったことに出来る(なのでread onlyにしておく)
後半はwritableセクションで結果をプログラム本体に反映させるが、その代わり例外(失敗)は許さない
bool func(){
  hoge_type result;
  try{ result = sub1(); sub2(); }catch(...){ /*リカバリ可能*/ return false; }
  try{ hoge = result; }catch(...){ /*リカバリ不可*/ abort(); } return true;
}
ただこれでもあまりうまくいかなくて、sub1()とsub2()が上記ルールに従ってたとしても
sub1()は成功してsub2()は失敗した場合に困る
全体としては失敗だけどsub1()は既に成功していて結果も反映されているので
sub1()の実行を無かったことにして巻き戻すのは難しい
sub1()をsub1_read_only()とsub1_writable()に分解するという方法もあるかもしれないが
データの受け渡しで苦労するし、可読性が落ちるうえ、複雑なことはしにくくなる

もう一つの別の要求もあって、重たい処理は別スレッドで実行して即座にGUIスレッドに制御を返したい
ということはユーザーは重い処理のキャンセルが出来るだろうが
処理のキャンセルは例外からのリカバリと本質的には全く同じこと
また、先ほどのread onlyセクションはプログラム本体の状態を書き換えない前提なので
別スレッドで実行したり非同期に同時並行で実行したりが出来る
(ただし、誰かがwritableセクションを実行したら、そいつ以外の処理結果は無効になる
 古いデータに基づいて処理した結果ということになるので・・)
0201デフォルトの名無しさん (ワッチョイ 8746-TjkM)
垢版 |
2017/11/29(水) 22:30:19.77ID:IulhJnoW0
上記のようなことを総合的にまとめると
void func(){
  // read only セクション
  barrier();
  // writable セクション
}
という結論に至った
ただし、func()はコルーチンから呼び出す
read only セクションでは、必要であれば処理を別スレッドで処理を実行することが出来、自身はyield_returnする
投げた処理が終わるとメインスレッドにて続きから再開してもらう
read only セクションでは、新たなコルーチンを作成することが出来、作成元のコルーチンと親子関係を構築する
親子関係を持つコルーチンの全てがbarrier()に到達するか終了してからでないとbarrier()以降は実行されない
親子関係を持ついずれかのコルーチンがread only セクションにて補足されない例外を発生するか
もしくは外からキャンセルされると、無かったこと扱いになって
全ての親子関係を持つコルーチンにおいてbarrier()以降は実行されない
(親子関係の有る複数のコルーチンの処理が一端barrier()で止まって、全てが成功したのを確認してからbarrier()以降が再開される)
コルーチンにはグループNoを設定することが出来る
違ったグループNoを持つコルーチンを同時に実行することはできない(終わるまで待つ)
同じグループNoを持つコルーチンは同時に実行できるが
いずれかのコルーチンがyield_returnした段階で、それと親子関係のあるコルーチン以外はすべてキャンセル扱いになる
たとえばボタンAを押して処理Aが始まったが処理Aが終わる前にボタンBが押されたら
処理Aはキャンセル扱いになって処理Bが反映される
キャンセルされると困るような処理は別のグループNoにしておく

というような感じでひとまず落ち着いた
グループNo周りはかなり暫定的な感じだが・・・
以上日記
0202デフォルトの名無しさん (ワッチョイ 3d9f-JjO2)
垢版 |
2017/11/30(木) 00:09:19.12ID:fhhh9IM80
32 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/26(日) 17:30:11.12 ID:DaGrByo80 [1/4]
C++入門書でよく勉強したはずなのにautoとかconstexprとか知らんもんが一杯…

35 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/26(日) 17:38:44.74 ID:DaGrByo80 [2/4]
>>32
やさしいC++第3版
大体9年前に買ったのを寝かしといて最近になって勉強し始めたが、そんなに仕様変更ないと思ってたが間違いだったようだ

36 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/26(日) 17:39:04.93 ID:DaGrByo80 [3/4]
>>33だった

39 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/26(日) 17:52:39.37 ID:DaGrByo80 [4/4]
Effective Modern C++17出たら買ってみるわ

95 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/27(月) 12:49:42.23 ID:vi7VqSly0 [1/2]
遠回しに他の言語の本読めって言っとるようなもんだ

98 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/27(月) 13:23:45.26 ID:vi7VqSly0 [2/2]
>>97
ああそういうことね

132 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/28(火) 12:26:15.71 ID:+ODnZXKO0 [1/2]
Java原人がいるようだね

156 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/28(火) 23:59:58.99 ID:+ODnZXKO0 [2/2]
ワッチョイって神だわ

199 名前:デフォルトの名無しさん (ワッチョイ 07eb-5mWG)[sage] 投稿日:2017/11/29(水) 21:47:36.72 ID:ZCDC/+v90
実際にスレ汚しとるのはお前だけどな


さすがゆとり、これらが役立つ投稿のつもりらしい。
0203デフォルトの名無しさん (ワッチョイ 5deb-JjO2)
垢版 |
2017/11/30(木) 00:38:22.38ID:trGz4Mxl0
いつの間にかIP信者になったんだ・・・W
0205デフォルトの名無しさん (ワッチョイ 3d9f-JjO2)
垢版 |
2017/11/30(木) 02:04:31.87ID:fhhh9IM80
>>200
SQLite3使ってみろ。

>>201
C++はyeildも入れたのか?と思ったがstd::yieldはただのsleep(0)か。
まああまり凝ったことしても、とも思うし、そもそもGUIはC++で無理に組む意味無いぞ。
それも含めて自由にやればいいとも思うが。


>>125
君は何が言いたかったのだ?

分かると思うが俺がゆとり死ねと言っている奴だ。
見る限り、君は話す気はあるようだ。
125は唐突過ぎてスルーしたが、相手してもいいぞ。

ただし125はバラけ過ぎているからテーマを絞れ、と言いたいところだったが、
その日記を読む限り上段落の話は一連のテーマか?
だったらWeb系の連中ならそこは「DBを使う」って事になっている。
C++は自前で何でもできるから、無意味なほど精神論で速度を追求するわけだが、
そこらへんをサクッと割り切るあいつらのやり方にも学ぶ物はあるぞ。
そもそも自前でトランザクションを実装するとか、検証の手間まで含めたらありえんだろ。
精神論でゴリゴリではなく、上手く手抜きするコツも覚えるべきだ。
0206デフォルトの名無しさん (ワッチョイ 8d46-5y5x)
垢版 |
2017/11/30(木) 03:11:44.92ID:b5fP6Zaz0
実際問題、メモリやデータだけを復元の対象とするとしたら
DBなど使わなくとも原本を保存しておけば何があっても元に戻せるのだが
そういう話ではないし
どのみち非同期処理にC#よろしくコルーチンが使いたいわけで
ただしそのままでは並行して細切れに処理が走って危険なので
書き込む前にbarrierを設けようというアイデアがまずあって
そうすることでついでに例外安全性も確保できるし
ならばキャンセル処理もできますわなぁという巡り合わさった面白い話
0208デフォルトの名無しさん (ワッチョイ 3d9f-JjO2)
垢版 |
2017/11/30(木) 07:37:52.31ID:fhhh9IM80
>>206
> 巡り合わさった面白い話
まあ俺は単に張り切りすぎだと思うけど、
そういうところを含めて無駄に熱いのがC++erのいいところでもあるとは思う。
Web系の奴らは上手くこなすことだけを考えていて、自分で考えることを止めてしまってる。
あれでは上達しないのも分かる。

>>200
一応捕捉しておくと、SQLite3はDBだが鯖形式ではなくCのライブラリ(DLL)だからC++から直接呼べる。(はず)
ソースはパブリックドメインだからDLできるし、もちろんincludeしても使える。
(https://www.sqlite.org/quickstart.html // サンプルが extern "C" ではなく include かよ!)
DBはメモリ上にも置け、当然爆速だ。自前でトランザクション/ロールバックの仕組みを作るよりだいぶ楽。
公式に素晴らしいドキュメントがあるから詳しくはそこを読みまくったほうがいい。
C++erなら問題はSQL位だが、どうせいつかLINQもC++に導入されるだろうし、予習だと思ってやっとけ。
0210デフォルトの名無しさん (ワッチョイ a66e-hJGX)
垢版 |
2017/11/30(木) 11:49:07.85ID:/QNJXUpA0
>>209
禿本4thのP.351あたり読んだ?
0211デフォルトの名無しさん (ワッチョイ 8d46-5y5x)
垢版 |
2017/11/30(木) 12:26:19.48ID:b5fP6Zaz0
一応いまのところこんな感じで書けるようになってる
やってることが非同期処理なので多少ややこしいのは本質的に仕方がない
int func_async( int n ){
 if( n == 0 ){ return 0; }

 a_wait() << [&]{ sleep( 10*1000 ); };
 //↑非同期で何か重たい処理
 //↑別スレッドに投げたのちyield_return;

 int resunt;
 a_sync() << [&]{ //コルーチン作成
  resunt = func_async( n - 1 ); //再起呼び出し
 };
 //throw nanika;
 //↑仮に誰かが例外を投げれば親子関係のあるすべてのコルーチンの処理が
 //↑キャンセルされて、どのコルーチンもbarrier以降は実行しない

 //barrier前なのでresultの値は不定
 barrier();
 //barrier後なのでresultの値が決まる
 return n + result;
}
int main(){
 a_sync() << [&]{ //コルーチン作成
  int result;
  a_sync() << [&]{ result = func_async( 10 ); }; //コルーチン作成
  barrier();
  printf( "%d\n", result );
 }
 message_loop();
 return 0;
}
0213デフォルトの名無しさん (ワッチョイ 9e9f-Cyes)
垢版 |
2017/11/30(木) 20:12:10.25ID:OtOqgvDg0
C++の名前空間と呼ばれるのがあまり理解出来ないんだが
Javaでいうパッケージ的なやつ?
それともそれを使うためのパスワード的なやつですか?
0214デフォルトの名無しさん (ワッチョイ 8d46-5y5x)
垢版 |
2017/11/30(木) 20:42:22.43ID:b5fP6Zaz0
>>212
複雑っていうけど、元から非同期処理なんか、どう書いたって複雑だろ
>>211はお遊びでワザとコルーチン作りまくってるだけだし
あの程度の事なら本当はこれでいけるわけで
int func_async( int n ){
 if( n == 0 ){ return 0; }
 a_wait() << [&]{ sleep( 10*1000 ); }; //非同期処理
 return n + func_async( n - 1 );
}
int main(){
 a_sync() << [&]{ printf( "%d\n", func_async( 10 ) ); };
 message_loop();
 return 0;
}
別に複雑と言うほどでもないし
非同期処理を同期処理みたいにかけるというだけ
あとはキャンセルと例外安全のためにbarrierの機能を追加しただけ
0216デフォルトの名無しさん (ワッチョイ 3d9f-JjO2)
垢版 |
2017/11/30(木) 21:03:11.80ID:fhhh9IM80
>>214
まず、君が書いているんだから君が好きなようにやるべきだし、
実験的な意味合いも含めて色々やること自体はいいと思うが、、、

非同期にしてるのは何故?GUIからの呼び出しでC#のasync Taskと同じ状況か?
それなら確かにどうしようもないが、しかし今見てみるとC#のasyncもだいぶ筋が悪いとは感じるね。
そのケースなら、普通にマルチスレッドした方がすっきり書けるはず。

あと、コルーチンからのthrowって、君の意図しているようにドミノ倒し的に回収できるものなのか?
これは俺が仕様を知らないだけではあるが、普通はコルーチンってそういう使い方しないと思うし。
0217デフォルトの名無しさん (ワッチョイ 8d46-5y5x)
垢版 |
2017/11/30(木) 22:29:42.54ID:b5fP6Zaz0
>>あと、コルーチンからのthrowって、君の意図しているようにドミノ倒し的に回収できるものなのか?
そういう風にコルーチンを実装した
具体的にはコルーチンのメンバにキャンセルフラグを持たせておいて
コルーチンを外部からキャンセルしたいときはそのフラグを立てる・・・だけ
コルーチンがyieldから再開したら真っ先にそのフラグを読みに行って
もし立ってたら自発的に例外を投げてスレッドを巻き戻す

>そのケースなら、普通にマルチスレッドした方がすっきり書けるはず。

あくまでこれは例だからなぁ
上で書いた内容もそうだけど、ひとつコルーチンがシングルスレッドというのがミソになってて
マルチスレッドだと排他処理が非常に面倒なことになる場面でも
コルーチンはシングルスレッドだから問題にならない
ただ、yieldの前と後ろで時間的につながりが無いことが問題になるので
誰かが何かを書き換える前にbarrier()を設けるルールを作って、他のコルーチンを無効にする
非同期処理なんかまともにやったら頭がおかしくなるに違いないので
横断的に静的に管理したいなぁと

今までコルーチンは全然使わなかったし、完全にマルチスレッド脳だったんだが
コルーチンはかなり脳の負担が少なくてよい
自分が動いているときは必ず他人は止まっているという性質が良い
yieldの前後だけ気を付ければ後は完全にシングルスレッドのノリで排他処理が要らない
ただ逆に同期オブジェクトをLockしたままyieldしたら終わるという

>C#のasyncもだいぶ筋が悪いとは感じるね。
正直、あれの使いどころは俺もよくわからないんよなぁ
複数のコルーチンが同時並行で走ったら危ないから結局画面をロックせざるを得ないんじゃないかとか
キャンセルを受け付けられるようにするためには例外安全についても考えないとダメなんじゃないかとか
色々思うところは有るが、実はよく知らん
0218デフォルトの名無しさん (ワッチョイ 8abd-17nN)
垢版 |
2017/11/30(木) 23:00:20.60ID:oM5vIjZA0
>>216
async/awaitのしくみはawaitするタスクの完了時に呼ばれるべきコールバック関数登録の糖衣構文にすぎないとかそんな感じ、
ttps://qiita.com/ryosukes/items/db8b45c8ea42f924f02f
(まんまC#の関数で説明したページもあったはずだがどっかいったのでJavaScriptの例↑

で、ネイティブスレッドX上でasync/await呼び出しをいくつ書いても上記コールバック関数は単一スレッドで実行されるので
Xに対して同期的なデータへのアクセスはロック不要

ウィンドーズホンのGUIをぬるぬる動かすのがほぼ唯一の存在意義
0219デフォルトの名無しさん (ワッチョイ 8abd-17nN)
垢版 |
2017/11/30(木) 23:07:19.56ID:oM5vIjZA0
つまり同一スレッド内であればasync/awaitをいっぱい書いても複数のコルーチンが順不同でresumeされる感じにはなるが真に同時並行で実行されることにはならない
0220デフォルトの名無しさん (ワッチョイ 8abd-17nN)
垢版 |
2017/11/30(木) 23:13:29.49ID:oM5vIjZA0
なお順不同なresumeというシチュは、関数A内でawaitされるasyncタスクB内でタスクCをawaitする…とかいったケースで容易に生じる
この場合A内のawaitに引き続くのコードと、B内のawaitに引き続くコードのは順不同でどっちが先にresumeされるかわからん
しかし真に同時並行ではなく、同期的
0221デフォルトの名無しさん (ワッチョイ b5b3-HgL3)
垢版 |
2017/11/30(木) 23:19:09.22ID:AS96YR/U0
ttps://stackoverflow.com/questions/1724036/splitting-templated-c-classes-into-hpp-cpp-files-is-it-possible

Your template classes must represent only data structures not the algorithms.
This enables you to hide more valuable implementation details in separate non-templatized class libraries,
the classes inside which would work on the template classes or just use them to hold data.

この回答の具体的な例を教えて頂けないでしょうか。

std::vector(データ)とstd::algorithm(アルゴリズム)と思ったのですが、
std;;algorithmはnon-templatized classではないですよね。。。
0222デフォルトの名無しさん (ワッチョイ 3d9f-JjO2)
垢版 |
2017/11/30(木) 23:40:55.16ID:fhhh9IM80
>>217
> あくまでこれは例だからなぁ
もしかしてコルーチンを自動的にマルチスレッド展開して加速させる為のラッパを用意してるってことか?
それならまあそのコードの感じになるのかもしれん。

ちなみに言っておくと、俺が普通に実装したら>>215と同じようなものになる。
単純に、「ディスパッチして、joinを待って、commitする」としか読めないコードにする。
ただこれは君ももちろん分かっていて、あのコードなのだとは思う。


なお俺はC#のasyncは設計ミス、
・UIコンポーネントがUIスレッドからでしか触れないこと
の対策だと思っている。あれが無いと毎回invokeするとか、ちょっと回りくどい書き方をするしかない。
実際、Thread->backgroundWorker->Task->async Task だったっけ?何度も変更されていて、
こういう場合は通常、
・修正している奴が馬鹿だから修正のたびに新たなバグを仕込んでしまい、収拾がつかない
わけだが、ヘルズバーグとMSがそこまで馬鹿なはずも無く、もう一つのケース、
・根本の問題を修正せずに表面的に対策をしているから、収拾がつかない
のだと思っている。そして、根本の問題は、最初に書いたUIガー、って奴。

これについて「根本のUIスレッドの問題直せやボケエ」ってをずいぶん前にC#スレで議論した覚えはあるが、
UIをマルチスレッドにして悲惨だった歴史が既にあるらしく、
「オメーがラップすりゃいいだけだろボケエ」と返され、あ、確かにそうだな、と思って終わった。
ま、とにかく、UI関係のコードをスッキリさせる為の物だから、気になってないのなら放置でいいと思う。


> yieldの前後だけ気を付ければ後は完全にシングルスレッドのノリで排他処理が要らない
コルーチンの方がいいケースについてか。
うーん、どうなんだろうなあ?俺もコルーチンはほぼ使ってきてないが、
マルチスレッドする場合にはほぼ干渉しない場合に限っていたから、
逆に言えば、コルーチンを使えばもっと並列化できるということか?
0223デフォルトの名無しさん (ワッチョイ fa96-JU5h)
垢版 |
2017/12/01(金) 09:48:37.54ID:eHCFERDK0
Eigenで透視投影変換行列を作るのは次の書き方でいいんでしょうか?
なんか結果をみても微妙にずれているのですが...

Eigen::Matrix4f perspectiveMatrix(float left, float right,
float bottom, float top,
float near, float far)
{
Eigen::Matrix4f m;
m << 2.0f*nearZ/(right-left), 0.0f, (right+left)/(right-left), 0.0f,
0.0f, 2.0f*near/(top-bottom), (top+bottom)/(top-bottom), 0.0f,
0.0f, 0.0f, -(far+near)/(far-near), -2.0f*far*near/(far-near),
0.0f, 0.0f, -1.0f, 0.0f;
return m;
}
0224デフォルトの名無しさん (ワッチョイ 8d46-5y5x)
垢版 |
2017/12/01(金) 09:59:25.68ID:DoXCr8LG0
await/asyncのコルーチンは並列化じゃなくて非同期処理を同期処理っぽく書くための物だとおもうよ
「これを実行して、終わったらこれを実行してね」
っていうときに、スタックの内容がそのまま残ってるからデータの受け渡しが楽というだけだろう
ただ>>220が言ってるように順不同のresumeが起こったらアブナイので
何か書き込む前にbarrierを張って自分に関係が無い実行中のコルーチンを全部キャンセルして始末してしまおうという
(実際にはbarrierだけじゃなくawaitのタイミングでも始末するようにしているが)
ただキャンセルするために例外安全性とかも重要になってきて
ここでもbarrierとコルーチンの仕組みがそのまま活躍するのが、なんか不思議な感じなんだが
読み込みオンリーだけどキャンセルできるセクションと、書き込みできるがキャンセルできないセクションに
処理を分けるというアイデアはなかなか汎用性が有るんじゃないかと
で、二つのセクションは別関数にせずにコルーチンでつないで一つの関数に収めbarrier前/後とし
barrier前ならawaitも使える、と、2,3のことが同時にかたづいて気持ちが悪い
0230デフォルトの名無しさん (ワッチョイ 3d9f-JjO2)
垢版 |
2017/12/01(金) 19:27:41.27ID:quTLstwT0
>>224
最終的に何をしたいんだ?
俺にはそこが見えない。

一つずつ詰めると、頭三行
> await/asyncのコルーチンは並列化じゃなくて非同期処理を同期処理っぽく書くための物だとおもうよ
> 「これを実行して、終わったらこれを実行してね」
> っていうときに、スタックの内容がそのまま残ってるからデータの受け渡しが楽というだけだろう
については同意する。これは>>218-220含めて3人の共通理解でいい。
(ただし俺には逆に、君自身は「並列化の為に」async/awaitを使おうとしているように見える)

> ただ>>220が言ってるように順不同のresumeが起こったらアブナイので
これについては、一般的には逆だ。順序が逆になったら危ないような物を非同期にしてはいけない。
違う言い方をすると、非同期の結果をbarrierを張ってキャンセルするのではなく、
barrier後に非同期にして、結果は必ずcommit出来る構造にする。

ちなみにJavaScriptの連中はここら辺が分かっていなくて、
(というより連中は制御構造云々を議論できるレベルではないのでこれ以前なのだが)
同期前提の制御構造で非同期を扱おうとするからおかしなことになる。
JavaScriptには非同期しかないんだから、選択の余地もないんだが。

C#のasyncはこれとはちょっと違って、イベントで起動するから必ずUIスレになるんだが、
それにジョブをやらせるとUIがカクつくから他スレッドを起動しろ、
しかしそれだと結果を画面に表示できないからそこだけUIスレッドを呼び戻せ、
ただこれだとソースが汚いから、asyncというキーワードをつけ、あたかも全てUIスレッドが処理しているように見せる、
みたいな、なんだかなあ、という状況になっている。
つまり処理順と処理スレッドを入れ替える為の糖衣構文のようなものであって、
本来のasync/awaitのように、非同期を同期的に書くための物自体ではない。ただしそうとも使えるから流用してるが。

それで話を戻すと、君は非同期部分に一般とは逆の「非同期の結果を普通にキャンセルできる構造」を作ろうとしているようだが、
これは何故?或いは何のメリットがあると考えている?
■ このスレッドは過去ログ倉庫に格納されています

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