C++相談室 part141
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の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/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
C++11以降はセーフになったらしい(キリ ttps://cpprefjp.github.io/lang/cpp11/static_initialization_thread_safely.html Double Checked Lockingはジャヴァのメモリモデルがうまく対応できてなくて騒ぎになったことがある技法 もし関数内static変数の初期化をDouble Checked Lockingを使わずにスレッドセーフにしようとしたら、 関数に入る度に毎回馬鹿正直にクリティカルセクションに入るために1000クロックぐらい捨てることになってしまうま スピンロックか何かの黒魔術で若干緩和する実装も有り得るかもしれんが基本は ジャヴァではなくてC++の処理系がdouble checked lockingする分には 処理系がサポートするネイティブなアーキテクチャのみ考えれば良いから 問題が生じることは無いはずでとりあえずはめでたいと思うが、 グローバルなスタティック変数のように実行前に初期化する仕様にいまさら変えられない事情でもあったか。 リンカにシンボルを渡す手段がイマイチ決め手に欠くキモス あと複数の翻訳単位間ではグローバル変数の初期化順序は保証されない(保証しようが無い)から そういう混乱を避けるために関数内staticは関数に入ったとき初期化されてホスイ 個人的には使わないから知らんが >>171 unique_ptr<int[]> u(new int[2]{6, 7}); ライブラリを作るときは、hpp にはクラスの定義を、cpp には実装を書く、と理解しています。 クラスのメンバでない関数はどう扱うべきでしょうか。 hpp にプロトタイプ宣言を、cpp に中身を書く、というので合っていますか。 なぜヘッダはクラス限定だとおもったんだ? それ以前にクラス以外では使用したことがないのか? 宣言(Declaration)と定義(Definition)は用語なんで覚えといた方がいいよ ヘッダに書くのはクラスだから関数だからとかじゃなくて、複数の翻訳単位(≒cpp)で共通で使うかどうかで決まる 1つのcppの中でしか使わず外に見せないクラスや関数はcppの中でいいよ >>190 inline なので(苦笑 >>191 ハ? 回答の体をなしていない。 > hpp にプロトタイプ宣言を、cpp に中身を書く というやり方は許容されるという意味か。 >>192 覚えました。それで? >>193 であれば、今私は複数の cpp ファイルを持つ予定はないので、ヘッダファイルは全く不要ということになります。 ライブラリなんだろ? 自分はcpp1つでも、他の人のcppで使わせるためのクラスや関数があるはずだ それをヘッダに書け >>195 その際、「プロトタイプ宣言はヘッダで、中身は cpp ファイルに」というルールかマナーか慣習はありますか >>196 特にないから適当に他人のマネしとけばいいと思う。 >>193 >1つのcppの中でしか使わず外に見せないクラスや関数はcppの中でいいよ staticは付けた方が良いですか?(苦笑 内部リンケージにするには static を付けるよりも 無名の namespace に入れる方が良いやり方 みたいな雰囲気があるんだけど、 インデントが深くなるのがなんか嫌なんだよね。 インデントは文法に影響しないわけだから、 付けないという選択肢もとれるけど、 それはそれでなんだかなぁって感じだし、 結局は static を付けちゃうんよ。 無名 (unnamed) namespace って使う? 関数よりファンクタの方が速いという情報を見たのですが、メンバ関数を入れ子クラスでメンバファンクタ化すると高速化が期待できますか? VC2017で試したのですがテスト用の関数が単純すぎるのかグローバルのインライン関数、クラスのメンバ関数、クラスのメンバファンクタで差異が見られませんでした・・・ どこに書いてもいいだろ 他人の書いたコードなんてどうせ誰も読まないし 読ませたいならドキュメントしっかりさせたほうがいい >>202 その「ファンクタの方が速い」ってのは、一般的に関数ポインタを介するのと比較して、だよ 理由はインライン展開できるからであって、その実験で差異が出ないのは当然 ストアドよりインデックスのほうが速いよってスレなかったっけ。 >>199 使う理由としてはメンバ関数を内部リンケージにしたらリンク速くなるかもという期待だけだな 実際速くなるか調べたことないけど 明示的にstaticとある方が読みやすいし、無名はデバッガで見たときクソ見辛くなるし c++はこういうダメ仕様多過ぎてうんざりだわ 腐ったビルド戦略のせいで無駄なオブジェクトコードの重複を生じるのはゼロオーバーヘッド原則に反しないのか?は疑問だな 極一部のマニアしか使わない機能付けてオナニーしてる暇があったら、いいかげん時代錯誤なビルド処理の抜本的な見直しをやってほしい メンバ関数の数はクラスのオブジェクト生成コストにどれくらい影響しますか? >>209 数によるコスト差0だよ >>210 計測したことあんの? ありがとうございます というのもメンバ変数がなく多数の関数をまとめただけのクラスがあるのですが、次のどれがいいのか悩んでいまして (1) 全部static関数にする (2) クラスをnamespaceにして全部グローバル関数にする (3) 呼び出す場所で逐次インスタンスを作成する (4) 呼び出し側クラスでこのクラスのポインタをメンバとして持ち、コンストラクタでインスタンスを受け取るまたは生成する この場合のベストプラクティスはありますか? 特に何もないなら2 templateと組み合わせるなら1とか3は多用するけど4は無いな ありがとうございます (2)でやってみることにします 1 は、どうして君はすべての関数を、static 関数にできると思ったの? static関数と、関数のライブラリ・モジュール化は関係ない 3, 4 は、どうして君は、関数を使うのにインスタンスが必要なの? インスタンスの関数は、他の言語ではメソッドと言って、 そのインスタンスのメンバ変数を使うものに対して、特別な名称を付けている。 つまり、各インスタンスで値が異なるもの メソッドは、一般的な関数とは異なる。 メソッドや一般的な関数と、関数のモジュール化は関係ない 例えば、Ruby では、 Math.log2( 8 ) #=> 3.0 このようにインスタンスを作らなくても、呼べる関数をモジュール関数と言って、 各インスタンスから呼ぶ関数を、メソッドと言って区別している そう言われるとそうですね オブジェクト指向ではmain関数以外全部クラス/構造体で作成するものだという先入観がありました >>214 無理矢理4にしたいケースを考えると、同じインターフェースを持つ関数群A,Bを場合によって切り替えて使いたい場合に敢えてインスタンスのポインタとすることもあるかな。今回の質問者の場合には当てはまらないだろうけど。 >>193 >1つのcppの中でしか使わず外に見せないクラスや関数はcppの中でいいよ 名前無しでも何でも良いが、その場合はクラスはnamespaceの中に入れないと危険が危なすぐる… 同じ名前空間に属する同じシグネチャのFoo::func()が異なる関数として複数のcppで定義された場合、 どっちが呼ばれるか定まらない処理系が実在する(VC++2010とか 多分ODR違反で未定義動作なんだと思う 曖昧さは、利点にも欠点にもなりうる。 namespaceのグローバル関数ではなくクラスのスタティック関数にすることで曖昧さがなくなりコンパイルエラーを避けられる場合がある。 >>219 訂正 CPPでクラスを定義する場合は無名namespaceに入れないと危険が危なすぐる、 無名namespaceは異なる翻訳単位間では別名として扱われるから安全 一方、名前付きnamespaceでは異なるCPPで偶然 同じ名前空間に属する同じシグネチャのFoo::func()が作られてしまう危険性を排除できない >>220 そのクラスに非staticなメソッドを設けたとたん、 >>219 と同じ話でどのFoo::func()が呼ばれるかわからないという不正な動作をする危険性が生じる 驚くべきことに、VC++2010の場合リンカが何のエラーも警告も出さない それでいてしっかり変な動作になる(a.cppで定義したFoo::func()を呼んだつもりがb.cppで定義された同じシグネチャの別のFoo:func()が呼ばれる >>216 C/C++では、staticなどキーワードが全く違う複数の意味で使われるから注意な。 Ruby では、関数名のバッティングを避けるため、2重に囲む。 module 内にclass か、class内にclassを作る module Net class HTTP end class FTP end end # インスタンス Net::HTTP.new Net::FTP.new >>224 rubyボットはお呼びでないからもう巣に帰ってくれ static みたいな複雑な概念を、初心者が理解するのは難しい スコープを限定する意味と、生成・破壊のタイミングの違いと、 2つの異なる概念を使うから、難しい C++ は、すべてのリソースの生成・破壊のタイミングを追っかけるだけでも、大変 ドワンゴ江添の本「C++11/14 コア言語」にも書いてあるけど、 呼ばれる関数を探索する方法に、Andrew Koenig が提案した、実引数依存の名前探索 (ADL)もある 実引数依存の名前探索とは、C++において関数呼出時に与えられた引数の型に依存して、 呼び出す関数を探索 (lookup)する仕組みのことである。 英語ではKoenig lookup、argument dependent lookup (ADL)、argument dependent name lookupなどと呼ばれる >>216 >>212 の(1)はクラスのstaticメンバ関数のことを言っているのだか、>>216 や>>226 を見てるとそれを理解していないように思える。 いつも書籍や他人の発言を引用して〜〜では、という書き方ばかりしているのを見かけるが、自分の中に落とし込んで理解できてないならわざわざ書き込まないでくれ。 質問(ネタ振り)に対して見当違いな返答は混乱の元ってのはその通りとして。 読者の立場では、話題が広がってくのは嫌いじゃない。 投稿者の意見として消化しきれてなくても、 参考資料として「誰それの書いたナントカって本では…」と 紹介してくれるのも有難いし。 その上で「あの著者/本は間違いが多い、例えば…」とか、 「記述が古い、新しい規格でもっと便利な機能が追加された」みたいな 追加情報(具体的なもの)が出てくればなお嬉しい。 名前なし名前空間を名前あり名前空間の中に作ることができる。便利ちゃあ便利。 namespace hoge { namespace { int foobar = 1; }; }; 64bit環境で文字列ストリームクラスstd::ostringstreamのインスタンスのスタックサイズが、 gccで376バイト, VS2017で232バイトもあるんだがもっと小さくできるんじゃないの? ちなみに、std::string はgccとVS2017どちらも32バイト。 どうよ? >>232 std::ostringstream は文字列の一種というよりも入出力の系統だし、 std::basic_ostream を抱えているのでそんなもんちゃう? 継承してるしデータとして保持しておくものでもないしな >>232 質問と関係ないけどスタックサイズって何かわかってないだろ ostream, ofstream, ostringstreamのスタックサイズはgccとVS2017でそれぞれ以下のようになる。 gcc: ostream=112, ofstream=264, ostringstream=232 VS2017: ostream=272, ofstream=512 ostringstream=376 どうよ? 間違えた。gccとVS2017は逆です。 何が言いたいというと、組み込みで気軽に使えるC++を目指すならiostream周りを何とかしないとね、という話。 組み込みで気軽に使えるC++を目指してないしどこまで削れるかはベンダーの努力次第 Cがコンパイル言語であるにもかかわらずprintf()系の構文解析でJITコンパイルする野暮ったさを解決すべく導入されたはずのiostreamがまったく活かされていないね。 その程度のスタック消費でヒーヒー言うような組み込み案件でiostream使わんだろ >>241 スタック消費でヒーハー言う組み込み案件に進出するのもC++のひとつの課題なのでは有馬温泉 組み込み界隈がC++を活用する目標があるのであってC++の目標ではない from_chars to_chars使えって話だろ それかfmt class C : public std::function<int(int)>{}; というクラスを定義して、 int f(int i){ return i + 1; } void main() { C c = f; int i = c(1); } みたいな使い方って出来ないのでしょうか? functional のヘッダを読んでみましたがさっぱりでした >>245 やりたいのはこういうこと? class C : public std::function<int(int)>{ using std::function<int(int)>::function; }; めっちゃ雑にやったけど、 実際にはスライシングに気を付けてな。 >>246 すいません、 知識不足でそのusingが何を意味しているのか分かりませんが、 std::function<int(int)> と、 class C : public std::function<int(int)>{} を、 外側から同じように使いたいという感じです。 現在は、 class C { std::function<int(int)> F; }; みたいになっており、 C c; c.F = f; int i = c.F(1); と、こんな風に使われています。 std::function<int(int)> を継承させてしまい、.Fを消したい感じです。 >>248 単純に class C : public std::function<int(int)>{} とした場合、当然だけどクラス C にデフォルトで定義されるコンストラクタは C::C(void); と C::C(const C&); だから、型が int (*)(int) であるような値を受け取る余地はない。 using std::function<int(int)>::function; を入れると基底クラス std::function<int(int)> のコンストラクタである std::function<int(int)>::function; をあたかも C のコンストラクタみたいにできる。 そんだけ。 public 継承してれば std::function<int(int)> の他のメンバはそのまま C のメンバとして 見えるからおおよそ期待する挙動になると思う。 >>249 なるほど、そういう意味だったのですね。 ちょっと試してみます。ありがとうございます。 >>237 2ファイル同時に編集なんてしたらあっという間に食い潰しそうね >>244 が提示してくれた from_chars, to_chars をgccに導入するにはどうしたらいい? WSLのubuntuを使ってるんだけど規定でfrom_chars, to_charsの定義されたヘッダーファイルが入ってないっぽい。 >>254 たしか8.0でまだ整数しか実装されてない C++テンプレートテクニック第三版っていつ出るんですかね? テンプレート引数がクラスでpush_back()メンバを持っているというようなことを検査することはできますかね? std::is_classとdetection idiomで可能かと でてくしょんいでおむってどの本見ればわかりますかね? std::byteの使い方がよくわからない。 暗黙の何とかを避けるのに使うんだろか。 単純にバイトを表現する型というのが必要となった char8_tと同じようなもん 1バイトサイズの整数のつもりでcharを使ったらstreamで困ることがあったりしたしね。 enum class byte : unsigned char { }; ってなってる。 そのベースの型は実装依存 型を取りだして使えってことなんだろうか なんでenum classなんだ? typedefと何が違うの? でも過去にそれで何かあったんでしょ 使うかどうかは任意だしある分には困らない is_enum_vがtrueになるとか違和感しかない >>265 なんで uchar8_t uchar16_t uchar32_t にしないんだろな >>273 ひとりで全部作ってんのか? 誰か使い始めたらそれに巻き込まれるんだよ ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる