rinatz / cpp-book Goto Github PK
View Code? Open in Web Editor NEWゼロから学ぶ C++
Home Page: https://rinatz.github.io/cpp-book/
License: MIT License
ゼロから学ぶ C++
Home Page: https://rinatz.github.io/cpp-book/
License: MIT License
https://rinatz.github.io/cpp-book/ch03-08-iterators/
ポインタはイテレータでもある。実際、std::initializer_listの
begin/
end`はポインタを返す。
イテレータを使用できるコンテナにC形式の配列がないのも気になる。そのためのstd::begin()
/std::end()
であるはず
以下のように書いた場合と同じ挙動になります。
std::vector<int> x = {0, 1, 2, 3, 4}; for (auto it = x.begin(); it != x.end(); ++it) { std::cout << *it << std::endl; }
この例に限った見かけ上の挙動という意味では同じと言えなくもないですが、正確さに欠けるように思われます。
netlify.comを使うとPRに対して自動的にpreview用のWeb siteを作ってくれる。
例としては
asciidwango/js-primer#1005
というPRに対してbot-userが生成完了を教えてくれて
https://deploy-preview-1005--js-primer.netlify.com/
みたいにPR番号を含むURLを吐いてくれる。
レビューしやすくなるのではないか。
ビルドはGithub Actionsにやらせて成果物をそのまま投げればいいと思われる
ref: Netlifyに7ドル支払った話(GitHub ActionsでNetlifyにデプロイする)
・・・ところで今ってgh-pages
へのデプロイは手動だったりしますかね・・・?
暗黙の型変換をしているわけではないので修正が必要です。
表題のようなものは現在のところ紹介されていないように見えます。
なお現在C++標準化委員会にはstd::valstat
が提案されています
https://onihusube.hatenablog.com/entry/2020/08/12/014639#P2192R0-stdvalstat---function-return-type
https://rinatz.github.io/cpp-book/ch02-09-function-objects/
std::function で関数ポインタやラムダ式を保持することが出来ます。 std::function を使うことで、関数ポインタのような複雑な構文が簡潔になるという利点もあります。
という説明では、「じゃあ全部std::functionを使えばいいのか!」というミスリードをしかねないという印象を受けます。最適化を阻害するというデメリットを語らないのはフェアではないように感じます。
また、std::functionのメリットが簡潔に書けるだけというのも違う気がします。それだけならusing aliasで型定義すれば済むはず。そうではなくて、型消去によって関数オブジェクトを配列に格納できるということが利点であるはずです。lambda式を含む関数オブジェクトは、引数と戻り値の型が一致していても別の型をもつため、配列に格納できないところを、型消去してくれるstd::functionによって達成できるわけですよね。
C++11ではCとのデータ構造互換を考える時に、これまでPODという概念を用いていたのをtrivial classとstandard-layout classに分離し、さらにtrivial classよりゆるい制約としてtrivially copyable classという概念を導入した。本当に必要な制約はtrivially copyable classまたはstandard-layout classであるため、PODはC++20でdeprecatedとなった。
したがってPODとはC++考古学の範疇であり、新たに説明するのは望ましくない。
ref:
7.12 共用体の章で
std::cout << static_cast<int>(v1.get_kind()) << v2.get_string_or("bbb") << std::endl;
とありますが,
std::cout << static_cast<int>(v1.get_kind()) << v1.get_string_or("bbb") << std::endl;
ではないでしょうか.
cpp-book-1/docs/ch07-12-unions.md
また,9.3 特殊化の章で
tenmplate
とありますが,
template
ではないでしょうか.
cpp-book/docs/ch09-03-template-specializations.md
対象は VC++ と GCC (MSYS2 などの MinGW を想定) の2つ
https://rinatz.github.io/cpp-book/ch07-11-structs/
C++において構造体は存在しません。struct
keywordとclass
keywordではアクセス指定に差があるのみです。解説文自体は正しいですが、項目の存在自体が、C#のそれのようなものと誤認させます。つまりstruct
を構造体と翻訳することそのものに問題があります。
バイナリデータの読み書きで使われるので、そういった利用シーンの説明があったほうがいいと思います。
詳しい解説は不要だと思うが、はじめて見ると戸惑うため紹介くらいはしておきたい。
構造体とクラスの違いを理解してない人をよく見るので
POD 型の説明も含めてほしいです。
構造体は POD 型の場合のみメモリレイアウトも C 互換になる(memset() が使える)
POD 型じゃないとクラスとしてコンパイルされる(memset() が使えない)
githubについて慣れてなく、Issuesに提起してよいのか分かりませんが、
の'std:size'という部分は'std::size'関数と解してよろしいでしょうか。
貴サイトにてC++勉強中です。よろしくお願いいたします。
#56 で追加された下記ノート(question)は、強すぎる主張により読者の誤解を招く表現になっていると感じます。
C++11より前は push_back という関数のみが末尾への要素追加を担っていました。 C++11で追加された emplace_back は要素型のコンストラクタに直接引数を渡すことができるので push_back と同じかそれ以上のパフォーマンスを得られます。 多くの処理系では push_back を実装するのに emplace_back を呼び出していますから 現代において push_back を使うべき理由は存在しません。
emplace_back
が導入されたC++11以降でも、既存変数からのコピー/ムーブを行うといったpush_back
のユースケースは依然として残っています。emplace_back
が有効のなのは、一部のコンテナにおいて巨大な要素オブジェクト型を格納するさいにメモリ確保を効率化できる可能性があるためです(導入当時のMotivation)。その意味では、vector<int>
例示における実質的なemplace_back
/push_back
差異はなく、やはり少々強すぎる主張と思います。
訂正:既存変数からのコピー/ムーブはemplace_back
でも実現可能でした。この部分は取り下げます。
struct S { std::string a, b; };
std::vector<S> v;
v.push_back({"abc", "xyz"});
// ↓の方が好ましい(ことが多い)
v.emplace_back("abc", "xyz");
https://rinatz.github.io/cpp-book/ch04-01-declarations-and-definitions/
では
定義は重複が許されません。
とあり、それ自体は正しいのですが、inline
指定されたとき、同一定義であれば重複していいというのが関数については古くから、変数についてはC++17からあります。これをスルーしてしまうとtemplateが説明できなくなります(ちらっとtempalteの説明を見た感じinline 指定が必要という誤った解説がされていたり関数テンプレートをやめてオーバーロードを使うなどというとんでも議論がされていてますがこれはまた別の話)
#67 ではStrict Aliasing Ruleについて論じたが、以下のキャストはそもそもpointer interconvertibleではないからStrict Aliasing Rule以前の問題だとする指摘がなされた。
class A {};
class B {};
A a;
B* b = reinterpret_cast<B*>(&a);
そもそも元スレのreinterpret_cast式は現在のWDによるといわゆるstrict aliasing ruleで定義されてません。pointer interconvertibleを満たさない場合には意味がすでに必要とされてないため、文面通りの「未定義行為」です。
— g_naggnoyil(gint, gchar **) (@gnaggnoyil) November 27, 2020
https://timsong-cpp.github.io/cppwp/n4861/basic.compound#4.4
4 Two objects a and b are pointer-interconvertible if:(4.1)
they are the same object, or
(4.2)
one is a union object and the other is a non-static data member of that object ([class.union]), or
(4.3)
one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object ([class.mem]), or
(4.4)
there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast.
[ Note: An array object and its first element are not pointer-interconvertible, even though they have the same address.
— end note
]
cc: @onihusube @yohhoy
https://rinatz.github.io/cpp-book/ch02-09-function-objects/
いきなりラムダ式の解説が出てくるのはいいとして、関数オブジェクトの解説ページのはずなのに、どこにも説明が存在しない。
#93 の修正を頂く前はダークモードで表示できていたと思うのですが、
どうもその修正後、表示できなくなっているようです。
Firefox 114.0.1 (64 ビット)で現象を確認しています。
オーバーライドするには派生クラスのメンバ関数に
override
をつけます。
もちろん習慣としては常につけたほうが良いのですが、オーバーライドになるかどうかは同じ名前・同じシグネチャであることがまず基準として有るのでその説明は必要ではないでしょうか。
override
キーワードはオーバーライドになってないときに不正ということにするという補助的な機能しかもちませんが、今の説明だと override
キーワードを付けることでオーバーライドになるというように読めてしまいます。
クラスが持つ変数をメンバ変数といいます。
C++ の用語としては data member です。 規格の日本語版であるところの JISX3014:2003 (C++03 相当ですが) においても「データメンバ」という語が用いられており、これを公式訳語とみなすのが妥当と思われます。
もちろんメンバ変数 (member variable) という語も広く用いられているので説明しておく必要はありますが、原則としては規格に沿った用語を用いるのが好ましいのではないでしょうか。
配列の要素数を取得する方法として std::extent
もあります。 これは C++11 でも使えるので紹介してはいかがでしょうか。
https://rinatz.github.io/cpp-book/ch06-02-new-and-delete/
でnew/deleteの解説がされています。
解説文で
new を利用して確保したメモリの解放を忘れるとメモリリークになります。 new と delete は必ずセットで使いましょう。
と書いているにもかかわらず、そのすぐ上のサンプルコードはメモリーリークしています(p1が開放されない)。
int* p1 = new int(100);
int* p2 = new int[5];// MEMORY LEAK!!!!!
delete p1; // new によって確保されたメモリを delete で解放
delete[] p2; // 配列の場合は [] を付ける
現代のC++において、動的メモリー確保はまずstd::vector
/std::string
のようなコンテナの利用を検討し、次にstd::unique_ptr
、その次にstd::shared_ptr
の利用を検討するべきでnew
/delete
を使う場面はただの一ミリも存在しません。
new/deleteをただしく扱うことは人類には不可能であることは明らかであり、解説の必要性そのものを再考するべきと考えます。
signed
を付けると正負両方の値が表現できます。 明示的に付けなくてもデフォルトはsigned
になります。
char
は signed char
ではありません。
メモリレイアウトで重要な概念であるため説明が欲しい。
そもそもなんで継承の説明のところにアクセス指定子の話がいるのか見当もつかないのですがそれはさておき。
https://rinatz.github.io/cpp-book/ch07-03-inheritance/
この表の意図が理解できません。多分左側がメンバーに対するアクセス指定子で、上の「継承したクラス」というのはpublic継承したときのことで、「その他」とはクラスの外から見た時の話だと思うのですが、まったく理解できません。
メンバーに対するアクセス指定子の話はもっと最初の
https://rinatz.github.io/cpp-book/ch07-01-member-variables/
あたりでしておくべき話で、そうすると自然と
https://rinatz.github.io/cpp-book/ch07-11-structs/
の内容が統合され #65 も解決して万々歳となるのではと思います
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.