C++相談室 part134
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part133
http://mevius.5ch.net/test/read.cgi/tech/1511509970/
このスレもよろしくね。
【初心者歓迎】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 >>272
そういう事言い出すと「関数名と機能が一致してる保証がゼロ」や「クラスメンバの隠蔽が完璧である保証がゼロ」などといくらでも難癖を付けれるナリ
ヒューマンエラーを理由に不要と結論付けるのならあらゆるコーディング規約が不要という結論になってしまう、これはいけない
命名規則は可読性の向上に結びつくものでなければならない、規約を違反する事で起きるトラブルはプログラマ側の責任、それは分かるよね? ヒューマンエラーが起きる部分は極力排除して機械任せにできる部分は機械任せにすればいい
ハンガリアンを導入する理由はもはや無いな。可読性悪いし。 >>278
いや、ハンガリアンは可読性はよくなる方だよ
整合性維持に難があるだけで 可読性ぐらいテンプレートによる高度なメタプログラミングに慣れた諸兄なら
ハンガリアンごとき目を慣らして解決できるはずなんじゃ… >>276 >>282
両者は共存不可能な対立概念ではないけどね。
細かいことを言わせてもらえば、
「ハンガリアンとポリッシュ」か「ハンガリーとポーランド」と
並べてくれた方が座りがいい気もするけど…。
「ハンガリアン記法とポーランド記法」だとあまり気にならない不思議。 >>266
名前付き引数イディオムとenable_if<is_same<...>::value>が最強と言うことだな
※プログラマが、使用者が型を間違えないようにと気を使うのが正しいなら、間違えたらコンパイルエラーになるこれが最強だろ? >>277
ちげえんだよんぁ
可読性じゃねえんだよ
>>268を見てみろよ、
読む時じゃなくて書く時のヒューマンエラーだ
なんで入り込んだのか全く分からんようなミステイクだ
プログラミングが工業的生産の一種なら、その手のヒューマンエラーは無い方がいい
で、改めて>>268を見てみると、「可読性」があってプレフィクスの間違いに気付いてはいるものの、
そもそも書く段でなんで間違えたのか、それが全く分からない
他人はおろか本人すらも自覚できない謎の理由でプレフィクスを間違えてる(これがヒューマンエラーなんだけどな)
なんで、後だしジャンケンだと、「プレフィクスが最初から無ければ、間違いも発生しえなかった」、とも言える
もしかすると、書く時に間違える/読む時に間違える の比率を考えると、ハンガリアン記法は書く時に間違えやすいが読むときに間違いにくい……のトレードオフなだけかもしれん
要するに、可読性と生産性のトレードオフだけなんじゃあねえのか?
それに、読む時のヒューマンエラーと書く時のヒューマンエラーをわざと混同してるのはいただけない void func(int a)
{
//aが何型かわからない
//アホかおまえは
} template <typename T>
void func(T lpszA)
{
//lpszって書いてあるからTはLPSTR型だな
//アホかおまえは
} >>288
func()が常に1画面に収まって1万行の関数とかでありえないという根拠は
>>289
テンプレート定義時の引数に対して引数内容固有の命名が難しいのは
ハンガリアンに限ったことではないからハンガリアンに対する批判になんね
テンプレート批判論者には考える力がないのかね… ごめ
×:テンプレート批判論者
○:ハンガリアン批判論者 テンプレートに対してはハンガリアンは全くの無力だよなあ
一貫性の観点からやっぱりハンガリアンは無い方がいいわ .>>290のレスを見てテンプレートの実体化時までハンガリアンが無力なことにされてはかないませんなあ… そもそも関数が長い場合は型情報を持たすのもありだよな
システムハンガリアンをやめさせようとして先に関数を短くしなきゃだめだなと追う結論に至って放置した //1万行の最長不倒関数を書く
//アホかおまえは void func(int lpszA)
{
//lpszって書いてあるからLPSTR型だな
//アホかおまえは
} >>295
「1画面に収まらない」を都合よく無視しないように システムハンガリアンはDWORDをintに型名変更するだけでその変数名全部終わるからなしかも一瞬で >>299
dwをiに置換するだけだからリファクタリングが楽っていう意味? まったく逆だ
dwからiに全部置換していかないと変数名の意味を為さなくなるからシステムハンガリアンは愚かさ甚だしいと云うておる アンパンマン調で例えるなら型名変えるだけでメンテ百倍みたいな 組み込み型はいいけどクラスはどうすんのさ
意味の分からないサフィックスを付けられても困るぞ ハンガリアン!新しい型だよ!
有難う!デザパタ娘ちゃん!
メンテ百倍!ハンガリアン! そもそもDWORDをintに変えることが滅多にない dwとか書かれてもDWORDの定義を知らないと意味不明だし
やるなら符号の有無とサイズが分かるように書かないと意味ないでしょ >>298
おまえは間違いなく1万行と書いた
その史実を誤魔化すことはできない
「ありえないという根拠は」という問いを反論として用いるのは
俺が「ありえない」と言った(事実と違うが)ことが
おまえが「ありうる」と思っているのと違ったからだろう
いずれにせよ「アホかおまえは」にふさわしいハチャメチャだな >>308
俺も使う
ただし名前そのものをポインタっぽくするだけで
ハンガリアンのプリフィックスとしてではない ハード直叩きのドライバ屋はデータバスやレジスタの幅を間違えると大変だから
物理層の実装ではハンガリアン使うこともあるよ >>313
むしろそれはアプリケーションハンガリアンじゃね? 間違えると大変だからハンガリアンを使ってはならないんだよ
偽の情報に頼るんではなくて元を逐一確かめないと 今勉強してるんだけどC++ではポインタを使わずに参照で書くのがデフォルトなの? >>315
不一致が存在しない事が保証されてれば問題無いんやな
そういう事ならつまり変数宣言とプレフィックスが全て一致してるかチェックするスクリプトとかがあれば満足って事でええんか? >>316
ポインタも必要に応じて使うけど、メモリ管理の煩雑さとミスの危険性を避けるために参照やスマートポインタやコンテナ、イテレータなど他に適切な物がある時はなるべくそちらを使うのが流儀かな。 >>316
デフォ・・・まあ、そう言えなくもないか
参照でもポインタでもどっちでもいい用途には参照
ポインタでしかできないことはNULLに++や絶対番地指定
参照でしかできないことは一時オブジェクトやコピコン類 書き込むときは参照ではなくポインタにしろと言ってた人がいた。
理由を聞いたら「なんか書き込んでる感がない」だった。 グーグル規約だと書き込む引数は参照ではなくポインタにしろってなってる
でも標準ライブラリが普通に参照で書き込んでるので意味ないかなと思う 好きな方使えとしか言いようがない
ただ参照はnullポインタが無いという特性はある >>322
自分もその人の気持ちは理解できた。
func(a, &b);
と書かれていると、bに結果を書き込んでいる感があるし。 レスサンクス
cからだからポインタで書いちゃいそうだわ ローカルで宣言したunique_ptrを他のメソッドに渡してデータをつめたいばあいってどういう引数で渡せば良いの?
unique_ptr<Hoge> ptr(new Hoge);
hogehoge(ptr);
Hogehoge::hoge(const unique_ptr<Hoge>& ptr){
ptr->aaa = 123;
}
これでいける?
なんかウェブサイトみてると&&二つとかあったりするの見かけて混乱してきた &&は所有権ごとぶん投げる時に使う
渡した後も呼び出し元で使うんだったらそれて合ってるぞ >>327
それだったらunique_ptrじゃなくて参照渡せば良いだけじゃ 知らない間に、&& みたいな参照渡しもできた
Rust の所有権ムーブの事 所有権を渡すのってstd:move()だと思ってたんだけどconst &&でもいけるの?? C++17でstd::iteratorが非推奨ってなっているみたいだけど代わりに何使うの? >>332
std::move は rvalue にキャストするだけで、それ自体にはムーブする機能はない。
実際にムーブの処理をするのはムーブコンストラクタやムーブ代入演算子の方やで。 && は単純に右辺参照って意味しかないから、 rvalue を受け取れるってだけ。
だけど lvalue でもムーブしてぇってときは std::move で rvalue にキャストすんの。 右辺値参照とか難しいなー
最近ようやくC++11使えるようになったから全然いってることがわからん 右辺値参照が使えなかった頃は、std::swapでスピード最適化していた。ポインタとメモリー確保を含む構造体は、
単純にスワップしたり、単純にバイト単位コピーしたりするのはまずいことがある。
そういうときに、std::swapを使う。右辺値参照は、それよりちょっと速くて賢いが、テンプレート型を理解してないと多分理解できないと思われる。 右辺値参照の型はテンプレートを使った特殊な型だと考えるのが自然。
T&& === rvalue_ref<T>.
std::move(T&)はrvalue_ref<T>という型。 訂正。
std::move(T&)の戻り値はrvalue_ref<T>という型。 すみません、テキトーなことを書いたので、銃殺されます。 実際のところヘッダファイルから std::move の定義を抜き出すとこんな感じ。
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept {
return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);
}
テンプレートの都合で面倒くさくなってるけど、実態としては static_cast してるだけ。 そのstd::remove_reference<T>::typeはTから左辺値参照や右辺値参照をはずした型になるね。それに&&を付けるんだから、左辺値参照が右辺値参照になる。 やはり、constexprやnoexceptを付けた方が性能がいいんだな。 C++17 では noexcept は型の一部という扱いに変更された。
例外を投げないなら投げないと書いておかないと他のライブラリとの組合せで型エラーになったりすることもあるかもしれんぞ。 江添本にこの辺りのチートシートと問題集いれたら100部くらい売り上げ増えるのでは 江添ってあれか。ニートの時にやることないからたまたま目についたC++の仕様書を読み込んでたら
いつの間にかすごく強くなったという、ホリランみたいな。 おまえそれをバカにできるのか?
仕事ってそういうもんだぜ
目の前の案件のために必死こいても付け焼き刃にできることは知れてるんだよ
「ヒマ」なときに遠くを見て投機的にコツコツ努力したことが
あとで花咲くことがあるし咲かないこともある
賭に勝った者を、降りたやつがバカにできるのか? え、おい >>320
>>322
書き込むときポインタ渡しにするのは
C++には参照渡しがin/out/refのどの意味なのか表すシンタックスが現状無いから
というのが主要な動機だと思うが
inならconst T& aというのは比較的読み筋だが
T* pと書いただけだとoutなのかrefなのかやっぱりわからん… && は、Rust のmove の事。
所有権移転。移転元が空になる
基本的に数年は、ドワンゴ江添と共に、山ごもり!
江添が空海なら、漏れは最澄w
悟りを開くまで、空海・最澄の一問一答が、延々と続くw rvalue reference 自体はムーブしねぇつってるだろ。 &&参照は「このオブジェクトもういらないからぶっ壊してもいいよ」というサイン
言うなれば肉屋へ行く馬車
野生のオブジェクトは誰に断る必要もないので勝手に連れてかれて解体される
家畜を渡す時は解体に同意するサイン(std::move())が必要 Fooクラスのunique_ptrがつまったvectorを作って、他クラスのメンバ変数にセットするときはどう渡すべき?
作った元ではもう使わないから所有権放棄していいとする
const参照渡しにして、渡された側でvectorの中身を全部std:move()して新しいvectorにつめるのが一番最初に思い浮かんだ
そんなことしなくても最近ここででてる、&&つけて渡してそのままセットすれば解決するのかな? vectorを丸ごとmove付けてコンストラクタに渡せばいいよ
出来上がった後で渡したいならswapすればいい なるほどー
コードにするとこんな感じかな?
std::vector<std::unique_ptr>vec_hoge;
...
Hoge hoge;
hoge.setHoge(std:move(vec_hoge))
Hoge::setHoge(vector<unique_ptr>&& vec_hoge) {
this-> vec_hoge = vec_hoge;
} せやな。
rvalue reference は lvalue だぞ。 noexceptにtrue,falseがある理由については
#include <type_traits>
template<typename T>
void test(T t)noexcept(is_unsigned<T>){
//Tの型がunsignedの時だけは例外は投げない
}
こういう事が出来ると書いてあったけど、c++17以降も問題なく使えるだろうか? is_unsigned_vだろ
なぜC++17以後で廃止になると思ったんだ? stdも抜けてた。。。
廃止になるじゃなく面倒な事になりそうだと。 unsigned は組み込み用だろ
0 〜 255 のカウンターなどで、無限にループする。
255の次に、0が来る
overflow にされると困る >>368
組み込みでなくても極々普通に使うし、標準ライブラリ使ってれば知らぬ間に使ってる。 普段は uint_xxt と size_t しか使わんわ
int と ptr あんまり相互に変換しないし visualstudio2017 でスタックトレースがしたいのですができません。
最初はBoost.StackTraceで試みたのですがMSVCでは行数やファイル名の出力が非対応で
アドレスまでしか取れませんでした。
次にWinAPIを使って解決させようとしたのですがこれもうまく行きません。
SymGetSymFromAddrを使うとどうやってもエラー126が帰ってきてしまいます。
以下のプログラムがVisualstudio2017で動作している人はいないでしょうか?
ttps://github.com/shive/blogpost/blob/master/20130918-stacktrace/main.cpp >>373
こうなった
---- BEGIN BACKTRACE ----
1 : 0x00e76873 : Project1 : mycode::foo : c:\users\\source\repos\project1\project1\main.cpp(116) :
backtrace();
2 : 0x00e76513 : Project1 : mycode::bar : c:\users\\source\repos\project1\project1\main.cpp(120) :
foo();
3 : 0x00e76563 : Project1 : mycode::baz : c:\users\\source\repos\project1\project1\main.cpp(124) :
bar();
4 : 0x00e76b33 : Project1 : mycode::hoge : c:\users\\source\repos\project1\project1\main.cpp(128) :
baz();
5 : 0x00e76f0d : Project1 : main : c:\users\\source\repos\project1\project1\main.cpp(134) : try {
6 : 0x00e7870e : Project1 : invoke_main : f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl(78) : ?
7 : 0x00e785b0 : Project1 : __scrt_common_main_seh : f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl(283) : ?
---- END BACKTRACE ---- ■ このスレッドは過去ログ倉庫に格納されています