C++相談室 part142

レス数が1000を超えています。これ以上書き込みはできません。
2019/04/01(月) 22:17:05.84ID:wmfpIKt/
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512

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

前スレ
C++相談室 part137 (正しくはpart138)
http://mevius.5ch.net/test/read.cgi/tech/1535353320/
C++相談室 part139
https://mevius.5ch.net/test/read.cgi/tech/1538755188/
C++相談室 part140
https://mevius.5ch.net/test/read.cgi/tech/1547326582/
C++相談室 part141
https://mevius.5ch.net/test/read.cgi/tech/1550772463/

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

■長いソースを貼るときはここへ。■
 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
2019/06/10(月) 22:04:08.27ID:irHYgLSK
utf8の文字定数って実質ASCIIしか使えないのかコレ
2019/06/10(月) 22:42:42.99ID:J/wxl4Rl
>>898
アマチュアをからかうプロwww
エンジニアがそんなんじゃ日本の将来は暗いわ
2019/06/10(月) 23:08:47.95ID:j+S7HtNV
ていうかテンプレートが絡むととたんに問題解決できなくなるプロ
2019/06/10(月) 23:51:39.69ID:Ii7tq5Jr
テンプレートの問題なんてもう語り尽くしたわ。
それでもバカがあと立たないのもずっと見てきた。。
2019/06/11(火) 00:19:02.01ID:QaZP7mkq
テンプレートの問題について何も聞いてないし、その状態で語り尽くしたというなら何も問題はないな。
2019/06/11(火) 00:19:41.89ID:kvB4pOtR
新規参入者がいるってことだから恐悦至極なのではないか
2019/06/11(火) 00:25:55.32ID:PO+d8+1v
(果たして彼にとってはテンプレートのみが例外的に特殊な問題であって
 テンプレート以外については十分なスキルを有しているのであろうか…
907デフォルトの名無しさん
垢版 |
2019/06/11(火) 00:53:07.47ID:7MvjruKl
コンパイル時に発見できるような問題はそもそもたいして深刻な問題ではない。
2019/06/11(火) 01:02:03.28ID:TJ/Njjhl
>>907
コンパイル時にわかる程度の問題でも、ランタイムでエラー吐かれたらデバッグ大変だよ
Pythonの型違いで嫌と言うほど思い知った
909デフォルトの名無しさん
垢版 |
2019/06/11(火) 01:13:48.45ID:7MvjruKl
>>908
私は、ランタイムエラーを解決することの困難さに比べればコンパイルエラーなんて大したことない、という意味で言ったんだが。
あなた、読解力がないって遠まわしに指摘されること多くない?
2019/06/11(火) 01:26:55.77ID:TJ/Njjhl
そもそも文脈不明な中でそれだけ書かれてもなぁ
コンパイル時の分かるような問題かどうかではなく、エラーをコンパイル時に吐いてくれるとデバッグが捗るみたいに書けば良いのに
実際、assertやstatic_assert
SFINAE使ってのなるべく上位レイヤーでエラー発生させるのは重要でしょ
2019/06/11(火) 01:51:30.87ID:GDgSrcmQ
テンプレート駆使したライブラリ使うと最適化ありなしで速度かなり変わるの困る
デバッグビルドだとくそおっそくてデバッグがままならん
なんか良い解決法ないですかね?
2019/06/11(火) 02:00:33.22ID:TJ/Njjhl
適当なところで切る
処理の定義を別ヘッダに分けて、特定のソースファイルで定義ヘッダを読み、デバッグが必要ないところは最適化Onで明示的インスタンス化をする
913デフォルトの名無しさん
垢版 |
2019/06/11(火) 02:07:42.02ID:7MvjruKl
>>911,912
> 処理の定義を別ヘッダに分けて、特定のソースファイルで定義ヘッダを読み

自前の切り替え処理自体が不具合の原因になりかねない。
素直にprintf()するのが一番確実でしょう。
2019/06/11(火) 02:12:17.79ID:bsFR+Nzy
C++14以降でテンプレートのデザインパターンの参考書って無い?
2019/06/11(火) 02:42:42.36ID:Pe41E3Zb
テンプレート完全ガイドの2版が出てたけど、英語
2019/06/11(火) 22:59:30.61ID:GDgSrcmQ
>>912
ソースファイルごとに最適化変えるのって簡単にできます?
VSプロジェクトかCMakeで
2019/06/12(水) 00:12:16.75ID:EuvWtF/E
VSならプロジェクトじゃなくソースのプロパティ選んで最適化変えればそこだけ反映される
まあ、それ用の構成作っておくのが安全

CMakeはわからん
makeなら簡単だけど
2019/06/12(水) 09:35:50.45ID:eCiQ25Tx
c++の場合、このコンパイラでは通るけどこっちのコンパイラでは通らないとかが
普通にある方が問題。
静的だとか動的かとかそういう問題とはまた違う。
2019/06/12(水) 09:39:04.87ID:dM+mHpC4
>>917
あ、ホントだ
ありがとうございます
2019/06/12(水) 12:59:45.38ID:pwRz5TOC
>>918
コンパイラごとに違う言語なんだから当然では?
むしろコンパイラが1つしかない言語以外でそういう問題が発生しない言語ある?
2019/06/12(水) 16:21:34.99ID:7KGE0Knu
Java、C#は「コンパイラが1つしかない言語」に含む?
どのみち比較の対象が少ないね。
2019/06/12(水) 16:22:16.09ID:7cC3bFV5
普通はコンパイラは何種類もない
2019/06/12(水) 16:24:55.92ID:EuvWtF/E
そこら辺もバージョン違いで色々あるよね
2019/06/12(水) 16:31:31.49ID:7cC3bFV5
そんなの当たり前だろ
2019/06/12(水) 16:40:28.14ID:7KGE0Knu
「コンパイラが通らない問題を解消するためにビルドツールをご用意いたしました。」
で、configureやらcmakeやらantやらといった車輪の再発明が続々生まれてくる。
2019/06/12(水) 17:19:03.04ID:79FLB/Pn
ブラウザ戦争に近いものがあるな
2019/06/12(水) 18:48:39.87ID:eqhLCWed
モダンなC++を学ぶべく右辺値参照について勉強しているのですがさっぱりわかりません
本に右辺値参照は実際は左辺値でstd::moveは実際は何もmoveしない
と書いてありましたが本当に意味がわからない
言葉遊びはいいからわかりやすく教えてくれ
2019/06/12(水) 19:07:22.06ID:iR6eT4Op
>>927
正確に言うと右辺値参照が左辺値なんじゃなくて右辺値を参照している「変数」が左辺値なのさ。
それ自体ひとつの変数なんだから当然のことだろう?
2019/06/12(水) 19:12:10.36ID:KzwP9Gzw
>>927
誤解を恐れずに言うと、std::moveを付けると、&&が付いた特殊な型になる。その型のことを右辺値参照という。ムーヴコンストラクターやムーヴ代入などは、その特殊な型に対して行われる。
2019/06/12(水) 19:17:22.52ID:KzwP9Gzw
&&が付いた引数は、中身の所有権を他の場所に譲り渡すことができる。
例えば、文字列クラスだったら、ポインタが指し示す文字列の所有権だ。所有権をコピーせずに、移動するだけなら、処理コストが低くて済む。
2019/06/12(水) 19:33:55.80ID:1cw0Fvdf
>>930
所有権って何ですか?
私は一つの関数で new/malloc() した領域を、別の関数に渡し、さらに別の関数で delete/free() してますが、効率よくそういうことをする場合には所有権という架空のフレームは邪魔だと思います
2019/06/12(水) 19:36:15.70ID:qnyyQkgz
>>931
まさにそれをする為のフレームやん。
2019/06/12(水) 19:38:15.23ID:eqhLCWed
>>928
あーなるほど確かに変数に代入してる時点でそうですね
右辺値参照を保持する左辺値ということですね
納得です

>>929
std::moveに渡す型も&&ですよね
&&をもらってさらに特殊な&&を返すんでしょうか?
remove_referenceとかその辺がさっぱりです
なぜこれが必要なのか
さらにその型で所有権が移るというのもよくわからず
2019/06/12(水) 19:45:51.10ID:qnyyQkgz
右辺値というのはほっといたら消える。

どうせ消えるんだったら右辺値が確保してるメモリ、こっちでちゃんと解放するからもらうね→所有権の移動

もちろん所有権移動したので右辺値でメモリ解放しちゃダメよ。
2019/06/12(水) 19:47:37.87ID:GZDxeRSP
>>933
所有権が移るというか...
T&& x を引数に持つ関数(コンストラクタが多い)は右辺値を受け取るけど、
そこで x の所有するリソースを
分捕っていいという「慣習」「イディオム」があるというだけなんだよ。
2019/06/12(水) 20:10:41.45ID:0iE+TYdc
>>933
そこを厳密に理解するには、lvalue, rvalue, prvalueなどの値カテゴリを理解しないといけない。
https://ja.cppreference.com/w/cpp/language/value_category
要するにlvalueをxvalueにするために、std::moveを使う。

remove_referenceは、type traitsと呼ばれる「型に対する演算」を行っているに過ぎない。
std::moveの実装のremove_referenceは、冗長な参照を削除している。
type traitsは、テンプレートに慣れないと使いどころが分からないだろう。
2019/06/12(水) 20:24:57.03ID:0iE+TYdc
class STRING
{
public:
...
// ムーヴコンストラクタ(一例です)。
STRING(STRING&& s) : m_ptr(nullptr)
{
std::swap(m_ptr, s.m_ptr);
}
// ムーヴ代入(一例です)。
STRING& operator=(STRING&& s)
{
std::swap(m_ptr, s.m_ptr);
return *this;
}
protected: char *m_ptr;
};
...
STRING s("abc123");
STRING t;
t = std::move(s);
2019/06/12(水) 20:34:03.21ID:0iE+TYdc
右辺値参照で挫折したら、Rustに進むがいい。
C++を完全に理解した人間は1%も居ない。
2019/06/12(水) 20:39:57.61ID:W9DAWVrH
蟻人間は行列理解からだな
2019/06/12(水) 21:02:08.90ID:KzwP9Gzw
あほですみません。。。
2019/06/12(水) 21:03:19.70ID:wMzR7R80
難しいというよりただ複雑
概念的にそれほど難しいわけではない
942デフォルトの名無しさん
垢版 |
2019/06/12(水) 21:07:19.74ID:JHNh+ipy
ムーブセマンティクスは今世紀最大の発明と言われてるからね。
2019/06/12(水) 21:11:21.95ID:7TWmWXJk
最近は標準ライブラリも文法も分かりやすくなったなと思ったら
initializer_list絡みの初期化がこのやろう
2019/06/12(水) 21:17:48.45ID:hxuK959+
・仮引数が右辺値参照&&なら、そこに渡した変数はぶっ壊される(そのかわり速いかもしれない)
・ただし安全のために使い捨ての一時変数か、std::moveを付けて「壊していいよ」と明示したものしか渡せないようになってる

これだけ理解してればだいたいOK
2019/06/12(水) 21:27:52.71ID:7cC3bFV5
ややこしいとか言う奴に限ってパターンの一覧表作っていつでも参照できるようにしないよな
2019/06/12(水) 21:52:10.38ID:eqhLCWed
このスレを読んだらだんだんわかってきました

>>937
なるほど
この例で使い方は何となく理解できたかもしれないです
abc123を一切コピーすることなく引き渡しているということですね
コンストラクタに右辺値が渡された時は自動的に&&のコンストラクタがよばれ(これはコンパイラが自動で判断してくれる)
コピーでは明示的に右辺値参照にしないとダメなのでstd::moveを使うと
2019/06/12(水) 21:59:50.66ID:eCiQ25Tx
右辺値判定はコンパイラ側も困ってそう
2019/06/12(水) 22:03:44.51ID:hxuK959+
厳密に決まってるから困らないぞ
949デフォルトの名無しさん
垢版 |
2019/06/12(水) 22:42:16.79ID:JHNh+ipy
【 constexpr の掟】
「ブッ殺す」と心の中で思ったならッ!その時スデに行動は終わっているんだッ!
2019/06/12(水) 23:19:39.59ID:zt+60oVn
>>931
所有権というのは権利を連想させるようないかにもお得な感じを醸し出しているネーミングだが
その実体はオブジェクトの開放を最後の一人だけがやる「義務」に他ならない

で、「最後の一人だけに開放させる」というのを>>931のように
>別の関数に渡し、さらに別の関数で delete/free()
というのは大悪手に他ならない
なぜなら呼び出し先で最後かどうかなど(所有権やレキシカルな手法では)管理し切れない
所有権は呼び出し元ががっちり掴んでおくもの
2019/06/12(水) 23:36:10.29ID:dKzVqNYa
moveしたあとの変数を使おうとしたらエラー出してくれるの?
2019/06/12(水) 23:44:04.96ID:vc+7745/
まさか
2019/06/12(水) 23:51:54.31ID:EuvWtF/E
元の内容について所有権を失っているだけで普通は使える様になっている
スマポならnull相当
vectorみたいなのならemptyもしくは何らかのごみが入っているのでclearか新たに代入すればおk
2019/06/13(木) 00:01:02.92ID:GxcaYm6A
>>953
>元の内容について所有権を失っているだけで普通は使える様になっている
moveしたあとの変数について述べているのなら完璧な間違いだ
藻前のプログラムはバグだらけだな
2019/06/13(木) 00:16:54.69ID:VunnpS2y
合ってるだろ
ムーブ後のオブジェクトは内容は未規定だけど有効な状態だぞ、少なくとも組み込み型と標準ライブラリはな
褒められたプログラミングスタイルかはともかく、再利用すること自体が即間違いとは言えない
2019/06/13(木) 00:26:16.00ID:/TtN03F/
>>951
ムーブコンストラクタを書いて自分で処理するんだよw
2019/06/13(木) 00:26:51.45ID:scxOg7Fk
コンパイル時に既に顧客の要求を満たしてるとかマジカッコいい
2019/06/13(木) 01:25:50.43ID:bj2tv0KH
少なくとも標準ライブラリでこれが出来ないと、メンバ変数の内容一つmoveしただけで親のオブジェクトまで使えなくなる。
メンバ変数再利用する術が無いってことだからね
2019/06/13(木) 01:41:54.12ID:/Ra8Vlso
>>957
未初期化の変数をコンパイル時に検出できるんだからmoveした後かどうかも判定できるはずでしょ
2019/06/13(木) 02:03:22.10ID:/TtN03F/
>>958
メンバ変数1つムーブって、どういうこと?
普通メンバ変数は右辺値にならないでしょ。
2019/06/13(木) 03:03:13.46ID:bj2tv0KH
2分木で子のスマポ所有しているような場合、付け替えとかで所有権の移動するときshared_ptrならコピーでokだけど、unique_ptrみたいなのだとmoveする事になるが、メンバ変数で持っていた子の内容をmoveしたあとその変数が再利用可能じゃないと困るだろ
2019/06/13(木) 03:21:55.87ID:/TtN03F/
>>961
c++11で導入されたmoveはいわゆる所有権の移動とは違うもなので、その場合はmoveは使えないと思う。
2019/06/13(木) 03:33:01.74ID:fPdkPYzy
>>962
unique_ptrのmoveが所有権の移動じゃないと言うなら一体何なら「所有権の移動」だと言うのか。
2019/06/13(木) 03:46:23.77ID:/TtN03F/
もともと右辺値参照とmoveセマンティクスの話じゃなかったっけ?
2019/06/13(木) 04:35:02.91ID:qBl/BLKs
ループの中で int a なる整数を使うとき、ループ内で毎回宣言するのとループの外で宣言して使い回すのどっちが結局速いの?
2019/06/13(木) 09:17:30.68ID:wJ3u1v7j
自分で計ればいいじゃん
2019/06/13(木) 11:30:46.72ID:eqzI8P56
ループの外に出せるものは可能な限りすべて出せ
2019/06/13(木) 12:09:07.93ID:Br82W2pC
範囲for文を使ってそんなどうでもいいことは忘れろ
2019/06/13(木) 13:18:06.43ID:XHz4etUG
>>967
逆じゃないか?
インスタンスの生成にコストがかかるときはトレードオフだが、そうでないなら可能な限りスコープを狭くなるように変数を宣言した方が良いと思う
2019/06/13(木) 13:33:35.83ID:eqzI8P56
スコープ気にするならループ関係の部分だけでスコープ区切ればいいじゃん
2019/06/13(木) 15:27:33.99ID:P5difHG2
>>970
お前は何を言ってるんだよ…
2019/06/13(木) 15:28:06.57ID:PncfQdvG
cppcheckやVisual Studioのような静的コード解析にかけると「スコープを小さくできるよ?」みたいなアドバイスが出るよね。
実際のところ、どうなんだろうね。typoしにくくなったりスタックサイズが小さくなる利点があるとは思うけど。
2019/06/13(木) 16:20:20.51ID:fzRArnQO
さすがにこの流れは草
2019/06/13(木) 16:22:08.63ID:jHLKLHUC
ちょうど今朝cppcheckかけたら
style: The scope of the variable 'c' can be reduced.
「変数 c のスコープを縮小できますよ」って出たわ。
つまり「スコープを狭くできるなら狭くすべき」っていう方針を、
(少なくともcppcheckを作ってる人は)採用してるんだろうな。

どっちが速いかについては、ちょっと最適化オプションつければ
結局同じマシン語になっちゃうんじゃないかしら。
2019/06/13(木) 16:29:14.63ID:gMp0DWLA
>>967
セオリーだからって鵜呑みにするの良くないよ
(というか文面だけ覚えても意味ない
2019/06/13(木) 16:30:01.81ID:57+ky1er
スコープ広いほうが良いなら最終的に全部グローバルにしろやになるやんけ
2019/06/13(木) 17:32:58.81ID:fC2jn4Im
オブジェクト指向って実はprivate変数のスコープをかなり広く取ってるセミグローバル指向だと思う
2019/06/13(木) 17:37:28.56ID:wJ3u1v7j
おれは思わないな
2019/06/13(木) 18:39:42.63ID:XHz4etUG
>>977
それってクラスを大きくしすぎているだけじゃないか?
2019/06/13(木) 19:54:06.23ID:fmTPRROb
この流れは関数切り出しをまともにやってない連中が多いってことだな。。
2019/06/13(木) 23:39:11.49ID:ktOVSBzy
そろそろ次スレ。わっちょい。
2019/06/15(土) 13:52:11.56ID:DKQ0QQLH
次スレ
C++相談室 part143
https://mevius.5ch.net/test/read.cgi/tech/1560574313/
2019/06/15(土) 18:36:57.85ID:YCpCWY7o
最近馬鹿の一つ覚えが多いな
>>982 乙乙
2019/06/15(土) 19:13:31.09ID:wEtwZJzN
覚えてるだけまし。
2019/06/15(土) 19:37:22.36ID:y49ayDRp
グローバル変数と言っているのはオブジェクト指向スレを荒らしてるバカだろ
986デフォルトの名無しさん
垢版 |
2019/06/16(日) 15:07:40.82ID:TXhOXCMI
任意の型に対応する整数を返すメタ関数ってC++11の標準であったりします?

intなら1
stringなら2
みたいな
上記の技法をなんと呼ぶかわからないので検索ワードも思い付かず…
2019/06/16(日) 15:52:45.94ID:eI7bdJXk
なんでワッチョイついてんの?
スレ立てミスだろ
2019/06/16(日) 16:00:01.99ID:gyfVRbSU
>>986
std::type_info::hash_code()が似た機能を持ってるけどメタ関数かどうかわからない。たぶんランタイム。
https://cpprefjp.github.io/reference/typeinfo/type_info/hash_code.html
2019/06/16(日) 19:19:35.33ID:PFinGY+5
質問ですがC++のクラスのメソッドは、大別すると、
コンストラクタとデストラクタとsetterとgetterと何になるの?
2019/06/16(日) 19:22:19.26ID:NJ2skO19
move? be?
ステートチェンジしていくのだから、動作になるのか?
2019/06/16(日) 19:31:47.13ID:Va3vueK+
setterとgetterって何?
Javaじゃあるまいしそんなの言語要素としては用意してないよ
2019/06/16(日) 21:57:17.90ID:PFinGY+5
>>991
setterとgetterが何かについてはググった方が良い

Javaは詳しくは知らないが、ググった限りにおいて
Javaでもsetter/getterを定義する専用の言語要素など用意されていない印象
2019/06/16(日) 22:03:52.19ID:PFinGY+5
で、C++/Javaどっちも
 { setter } ∪ { getter } ⊂ { メソッド }
であることは明らかだが、では
 Q1. { メソッド } - ( { setter } ∪ { getter } )には何か専用の名前は無いのか?、
というのが>>909の質問の主旨。

ついでに言うと
 Q2. { setter } や{ getter }というのは本当に確定した集合なのか?
と、
 Q3. 「操作」と言ったときそれは{ メソッド }を指すのか { メソッド } - ( { setter } ∪ { getter } ) を指すのかどっちなんじゃ、
とかも知りたい
2019/06/16(日) 22:04:40.86ID:fCIbdDP9
>>989
シグナルとスロット(Qt脳)
2019/06/16(日) 22:54:20.07ID:PFinGY+5
>>994
シグナルとスロットというのはGUI操作を処理する目的のブツなので、
実行時の時間コストがゼロコストに近いことを気体されているハズ、
よって { メソッド } - ( { setter } ∪ { getter } ) の全て(この中には実行時の時間コストが青天井のブツも含まれる)を
包含しはしないのではないか、

まあここまで書いてオモタが、 { setter } ∪ { getter } こそ実行時時間コスト0を期待されるから、
setterやgetterは次の定義で良いのではないかという気がしてきた…

- 属性を取得する目的の操作であり、かつ実行時時間コスト≒0の実装が今現在も保たれているのがgetter

- 属性を変更する目的の操作であり、かつ実行時時間コスト≒0の実装が今現在も保たれているのがsetter
2019/06/16(日) 22:56:35.57ID:PFinGY+5
後ろ2行訂正orz、
正:
- 属性を取得する目的で設けられた操作であり、かつ実行時時間コスト≒0の実装が今現在も保たれているのがgetter

- 属性を変更する目的で設けられた操作であり、かつ実行時時間コスト≒0の実装が今現在も保たれているのがsetter
2019/06/16(日) 23:24:38.97ID:PFinGY+5
補足すると、「属性を取得する目的」や「属性を変更する目的」というのは、
インターフェースをクラスの主要な機能とは独立に変更できることを暗に言っている

例えばクラスFooのsetBar()が真にsetterならば、
属性をsetterでセットするのをやめて(Foo::setBar()を廃止して)ファイルから
直接読み込むメソッドFoo::readFromFile()に置き換えても、
クラスの主要な機能Foo::mainFunc()は変更せずに済むハズ

getterについても同様
2019/06/16(日) 23:56:38.00ID:WOfC/Ugn
operator=がsetterでoperator()がgetterにならない?
2019/06/17(月) 00:00:50.16ID:x+yzwFNm
c++かどうかなんて関係ない、オレオレ分類しているだけだろ
2019/06/17(月) 00:01:28.14ID:7HzfXopw
ずれてるのを承知で書くけど、直接読み込むメソッドってやつも含め setter なんてない方がいいよ
レス数が1000を超えています。これ以上書き込みはできません。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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