2022年3月の日記

Unknown programmer's programming note.

2022年3月31日 (木)

雨、曇り

皮膚科

疣の治療。
もう何回目か分からない。
いいかげん終わってもいいだろうと思うのだが…
慣れているとはいえ、やはり治療後はしばらく痛む。

UNIXプログラミング環境 第3章と付録1を読み終えた

第3章はシェルの章。
初歩的というか、基本的なことに止まっている。
解説は本質を突いたものであって、ただ機能を羅列するだけものとは一線を画している。
ちらほら知らないこともあった。
次の章の目玉は、sedとawkだろう。
ちゃんと訓練したことないので楽しみだ。

付録1はedの要約だ。
せっかくだから覚えて使ってみようと思い、先に読んでおいた。
覚えることはそんなに多くない。
だからといって簡単というわけでもない。
これで現代のプログラミングするのは曲芸に近い。
マスターして人前で披露すれば注目を集められるだろう。

2022年3月30日 (水)


ファイルの削除権限

勘違いしていた。
ファイルのパーミッションに w がなくても、そのファイルを含むディレクトリの書き込み権限があれば、rmでそのファイルは削除できる。
(ただし、確認メッセージが表示される。)
ファイルを他のユーザーに絶対削除させたくないなら、ディレクトリのwを外しておかないといけない。
親ディレクトリにwが付いていたら、そのサブディクトリにwが付いてなかったとしても、rmdirやrm -rで削除できる。
しかし、削除しようとしているディレクトリが空でなくかつwが付いてなければ、それらの削除に失敗するので、基本的には削除できない。
…とややこしいこと考えなくても、ディレクトリからxを外しておけば、そのディレクトリに対する操作はできなくなる。
つまり、削除できなくなるし、lsやchmodもできなくなる。

ディレクトリのatime

Linuxの多くでは、ディレクトリにlsしたり、cdしたりするだけではatimeは更新されないようだ。
ディスクのマウント時にオプションrealtimeが付いていると、そうなるらしい。
別にnoatimeというオプションもあるようだが、何なのか分からない。
参考

UNIXプログラミング環境 第2章 読み終えた

ファイルシステム。
デバイスファイルのことほとんど何も知らなかった。
ちょっと触った程度だが解説されていて良かった。

2022年3月29日 (火)

曇り

fishのチュートリアルを読んだ

2022年3月28日 (月)

晴 (風強い)

UNIXプログラミング環境 第1章 読み終えた

UNIXを初めて使う人を対象とした章。
すでにUNIX環境に慣れている人は飛ばして良いと書かれていたが、一応読んでおいた。
#で1文字削除とか、@で1行削除とか、今では見られない環境で書かれている。
この辺りの違いは無視しても良いだろう。
また、誤植がやや目立つ。

fishをちゃんと覚えようと思う

UNIXプログラミング環境を読み始めて、特にシェルに関してちゃんと向き合ったことがないのに引け目を感じてきた。
去年からfishを使っているが、それまでは初期のbashを使っていて、だいたい適当に書いていたし、便利な機能を調査しようとしたりもしなかった。
だいたいでいいだろう、といった感じで。
今態度を改めようとしている。

2022年3月27日 (日)


Lua入門その4 書いた

数ヶ月ぶりに記事を書いた。
とっかかりだけ書いておいた二次方程式の解を求めるというもの。
久々だというのもあって、半日くらいかかった。
文章書くのが遅い。
練習あるのみ。

2022年3月26日 (土)


PacktのReaderが直っていた

良かった。

Learning Boost C++ Libraries 第4章を読み終えた

テキスト処理。
String Algorithm と Tokenizer と Regex。
積極的に使っていきたい。
Regexは標準ライブラリのを使った方が良いかも。

2022年3月25日 (金)

曇り

PacktのReaderがおかしい

何か開くと真っ暗になる。
Free Learningからアクセスした場合になるようだが、前日見れていたのに見れないのもある。
不安になるので、早く直して欲しい。

2022年3月24日 (木)

曇り

raylibの他言語バインディング

ここにraylibのバインディングが色々ある。
シンプルなライブラリであるためか、SFMLよりもたくさん作られている。
聞いたことのない言語もある。
すごい面白そうだ。
C++のラッパーもある。
まずは基礎になるCに慣れてからの方が良いだろう。
慣れるっていってもAPIは極めて直感的なので、迷うことはあまりないだろう。
関係ないけど、Crystal、Elixir、Odinと並べるとFFっぽい。

Learning Boost C++ Libraries 第3章を読み終えた

まるまるスマートポインタの章。
intrusive_ptr以外は、標準ライブラリに同様のものがある。
標準ライブラリの方を優先して使う方が良いと書かれている。
一番驚かされたのは、make_sharedについてで、make_sharedを使った場合と使わずにshared_ptrを直接作成した場合とで違いがあることだ。
shared_ptrには、shared_ptrのリファレンスカウントと、weak_ptrのリファレンスカウントの2つがある。
普通にshared_ptrを作成した場合は、それぞれ別に管理されるらしい。
そして、shared_ptrのリファレンスカウントが0になったら、管理しているオブジェクトは解体され、メモリも解放される。
しかし、make_sharedで作成した場合は、shared_ptrとweak_ptrのリファレンスカウントが同じブロックで管理される。
そのため、shared_ptrのリファレンスカウントが0になっても、weak_ptrのリファレンスカウントが0でなければ、メモリは解放されないらしい。
オブジェクトの解体はされる。
これはboost::make_sharedの話なのだけど、std::make_sharedでも同様なのだろうか。

本を買った

4冊買った。
数学の本3冊と、オライリーのRustの本。
Rustは第1版を持っていて、さっと目次に目を通して、それほど大きく変ったようには見えなかったのだが、一応確保しておいた。

2022年3月23日 (水)

曇り、雨

Learning Boost C++ Libraries 第2章を読み終えた

良い感じだ。
続けて読んでいこう。

raylib を使ってみた

前から気になっていたゲームのフレームワーク。
公式サイトのサンプルがおしゃれで使ってみたくなる。
Solusではeopkgでインストールできるようだったから、やってみた。

$ sudo eopkg install raylib-devel

サンプルをいくつか動かしてみた。
物理のサンプルはphysac.hというのを使っているのだけど、なぜかそれはインストールされなかった。
githubから入手して、適当に配置する。
ヘッダー一つだけなので、プロジェクトごとに含めても良いかもしれない。
raylibの使い方は直感的だ。
大量のCの関数が用意されていて、その中から必要なものを選んでいけばよい。
SDLやSFMLよりも機能豊富で、高いレベルでのプログラミングができるといった印象。

2022年3月22日 (火)

雨、曇り、晴

疲れた

仕事場のネット電話回線が死んでいて、いつもの倍疲れた。

Learning Boost C++ Libraries という本に着手した

この本を買ったのは、Packtのサブスクリプションや年末のセールを知らないときだった。
Amazonで4500円くらいで購入した。
最初パラパラと流していると、いまいちな印象だった。
Modern C++ Cookbookも最初そんな印象だったのだが、じっくり読んでみると、印象とは違ってかなり身になることが書かれている。
文章も読みやすい。
この本もそんな感じだ。
まだ第2章で、ウォーミングアップといったところだが、中々面白い。
Optional、Tuple、Variant、Anyと続いている。
どれもC++17では標準ライブラリに取り込まれている、Boostの方を使わずとも良いのでは、と価値を低く見積もっていた。
しかし、Variantのstatic_visitorの使ったサンプルなど、知らないことが書かれていた。
十分に時間を掛けて読む価値がある。

2022年3月21日 (月)

曇り

std::stringのストレージは連続しているブロックとは限らない?

Optimized C++ §11.1.6 (P248) に次のように書かれている。

stream_read_sgetn() と stream_read_string() の問題点は、ポインタ &s[0] が連続ブロックストレージを指していると仮定していることだ。C++11以前、C++標準は、文字列の文字が連続して格納されることを要件にしてなかった。ただし、私の知る限り、すべてのライブラリが連続するようにコードを書いていた。C++11標準では、箇条 21.4.1 で明白に文字列ストレージは連続と述べている。

文字列が連続していないという状況が想像し難い。
まさか文字データをリンクリストで保持する可能性があるなどということではないだろう。
調べないと分からない。

推測:
もしかして、物理メモリ上で連続していない可能性があるという意味だろうか。
OSが管理する仮想メモリ上で連続していれば、プログラムからは連続しているように扱えるので、パフォーマンスを無視すれば、問題ない。
例えば for (char *p = &s[0]; p != &s[s.size()]; ++p) *p = 'A'; のようにやっても問題ないはずだ。
そう考えると、まずまず腑に落ちる。

Opetimized C++ 読み終えた

読んでいて面白い内容ではあったが、やや難解なところもあり、同時に苦痛も伴った。

2022年3月20日 (日)

曇り

Opetimized C++ 進行中

10章まで読んだ。
今11章の途中。
前半はかなり難解だった。
今日中に読み終えたかったが、もう眠いので明日に回そう。

2022年3月19日 (土)


Modern C++ チャレンジ 第1章をやり終えた

数学の問題なのだが、数学の議論はしていない。
ただWikipediaを調べて、その要件を満たすようにコードを書けばよい。
調べずにやるのは無理だ。
例えば、アームストロング数が何なのかとか知っている人は、おそらく少数派ではないだろうか。
どういうものかの情報さえあれば、難易度は低い。
今後に備えたウォーミングアップといったところだろうか。
ただし、模範解答のようなクリーンで簡潔なコードを書くのは難しい。
とりあえず動けばいいやというような姿勢だとなおさらだ。
ここやるの2回目なのだけど、やっぱりお手本のようにはならなかった。

2022年3月18日 (金)


明日から3連休

ゲームもしたいところだ。

2022年3月17日 (木)

曇り

皮膚科行ってきた

疣の治療、もう何回目か忘れた。
3ヶ月通っている。
そろそろ終わっていいんじゃなかろうか。
まだ直ってないんだろうか。

C++ Game Development By Example 第13章まで読み終えた

Vulkanに入った。
ほとんど Vulkan Tutorial を読み易くしたものといっていい。
あと2章もVulkanの章だが、体験入門程度に終わるだろう。
ゲームを作るまでには至らないだろう。
そう考えるとVulkanを取り上げる必要はあったのだろうかという気がしないでもない。

2022年3月16日 (水)


Vulkanやばい

思ってた以上にやばい。
こんなの使いこなせる気がしない。
全体を把握した上で、APIのパーツをしっかりと理解して、1ステップずつきっちり進めていかないといけない。
こう書いておけばとりあえず動く、っていうのは通用しない。

2022年3月15日 (火)


C++ Game Development By Example 第11章を読み終えた

ライティングもやった。
基本的なフォンライティング。
相変らずスペキュラーの効果が分かりづらかった。

vkd3d

eopkgで「vulkan」をキーワードにしてパッケージを検索すると、vkd3dというのが挙がってくる。
これは、vulkanの上にDirect3D12のAPIを構築したものらしい。
どの程度再現されるのだろうか。
「DirectX12の魔導書」という本を持っているのだが、Windowsがないので読まずに積んであった。
もしvkd3dの再現度によっては読んでもいいかもしれない。
また姉妹書ともいえる「HLSLの魔導書」という本も出ている。
これは所持していない。

2022年3月14日 (月)

曇り

C++ Game Development By Example 第11章途中

メインはFreeTypeを使ったテキストのレンダリング。
ハッカーと画家という本に、「何でただテキストを表示させるだけに、こんなにコードが必要なんだ?」というのがあった。
それとは関係ないけど、FreeTypeもやはりかなり量のコードが必要になる。
その分細部までチューニングが可能となっていて、見返りは大きい。

あと少し、ライティングだけ残している。
これが終わったらいよいよVulkanだ。

2022年3月13日 (日)

曇り

C++ Game Development By Example 第10章を読み終えた

目玉はBulletの導入。
ボールが落下して、地面に当たって跳ね返る。
BulletのAPIは複雑だが、自力で作ったらどれだけ大変かを考えれば、十分に見返りはある。
欲を言えば、ただAPIの使い方を覚えるだけではなく、どのような計算が行われているかも知りたいところ。
しかし、この本の趣旨は実例のゲームであって、ゲームを完成させることを重視するのは真っ当なことだ。

2022年3月12日 (土)


Bulletの BT_USE_DOUBLE_PRECISION

なんとなく分かってきた。
どうもビルド時に -DBT_USE_DOUBLE_PRECISION を指定した場合に、そのライブラリを利用する場合は、クライアントも同様の指定が必要になるようだ。
Bulletをビルドするとき、ルートにある build_cmake_pybullet_double.sh というシェルスクリプトでビルドを走らせた。
このスクリプトの中にcmakeのコマンドが書かれていて、次のようになっている。

cmake -DBUILD_PYBULLET=ON -DBUILD_PYBULLET_NUMPY=ON -DUSE_DOUBLE_PRECISION=ON -DBT_USE_EGL=ON -DCMAKE_BUILD_TYPE=Release .. || exit 1

-DBT_USE_DOUBLE_PRECISION が含まれているのが分かる。
従って、このスクリプトを使ってBulletをビルドした場合は、アプリケーションも常に -DBT_USE_DOUBLE_PRECISION の指定が必要になるという寸法だ。

最初、このスクリプトの存在を知らずに build_cmake_pybullet_double.sh を使わず直にcmakeを叩いてビルドを実行した。
その場合、生成されたライブラリのバイナリは .so ではなく .a になった。
それをインストールしてアプリケーションをビルドしようとすると、ほとんどがundefined referenceになってリンクエラーになった。
この辺りの挙動もよく分からない。

cmakeのfind_package

Bulletのソースのルートに UseBullet.cmakeBulletConfig.cmake.in というファイルがある。
これらのファイルは、Bulletのビルドのために使われるのではない。
BulletConfig.cmake.in は、Bulletをビルドするとそれを元に BulletConfig.cmake というファイルが生成される。
インストールすると両方とも /usr/local/lib/cmake/bullet に配置される。
cmakeには find_package というコマンドがある。
システムに配置されている専用のcmakeのファイルを、特定の名前のパターンで検索して、利用しやすくするためのコマンドだ。
BulletConfig.cmakefind_package のために用意されている。

find_package には2つのモードがある。
モジュールモードとコンフィグモードだ。
どちらを利用しても BULLET_INCLUDE_DIR や BULLET_LIBRALY_DIRS といった変数が定義される。
それらを target_include_directories や target_link_directories に設定することができる。

target_include_directries(myapp ${BULLET_INCLUDE_DIR})
target_link_directories(myapp ${BULLET_LIBRALY_DIRS})
target_link_libraries(myapp ${BULLET_LIBRRIES})

さらに BULLET_DEFINITIONS という変数もあり、これに先の -DBT_USE_DOUBLE_PRECISION が入っている。

target_compile_definitions(myapp ${BULLET_DEFINITIONS})

これらのように指定できれば話は簡単なのだけど、モジュールモードもコンフィグモードもどちらもすんなりはいかない。

まずモジュールモードでは BulletConfig.cmake は使われない。
そのためか BULLET_DEFINITIONS が定義されない。

コンフィグモードでは BulletConfig.cmake が使われる。
しかし BulletConfig.cmake の中身が奇妙だ。

#                                               -*- cmake -*-
#
#  BulletConfig.cmake(.in)
#

# Use the following variables to compile and link against Bullet:
#  BULLET_FOUND              - True if Bullet was found on your system
#  BULLET_USE_FILE           - The file making Bullet usable
#  BULLET_DEFINITIONS        - Definitions needed to build with Bullet
#  BULLET_INCLUDE_DIR        - Directory where Bullet-C-Api.h can be found
#  BULLET_INCLUDE_DIRS       - List of directories of Bullet and it's dependencies
#  BULLET_LIBRARIES          - List of libraries to link against Bullet library
#  BULLET_LIBRARY_DIRS       - List of directories containing Bullet' libraries
#  BULLET_ROOT_DIR           - The base directory of Bullet
#  BULLET_VERSION_STRING     - A human-readable string containing the version

set ( BULLET_FOUND 1 )
set ( BULLET_USE_FILE     "lib/cmake/bullet/UseBullet.cmake" )
set ( BULLET_DEFINITIONS  "-DBT_USE_DOUBLE_PRECISION" )
set ( BULLET_INCLUDE_DIR  "include/bullet" )
set ( BULLET_INCLUDE_DIRS "include/bullet" )
set ( BULLET_LIBRARIES    "LinearMath;Bullet3Common;BulletInverseDynamics;BulletCollision;BulletDynamics;BulletSoftBody" )
set ( BULLET_LIBRARY_DIRS "lib" )
set ( BULLET_ROOT_DIR     "/usr/local" )
set ( BULLET_VERSION_STRING "3.21" )

奇妙なのは、パスが include/bullet のようにフルパスになっていないことだ。
BULLET_ROOT_DIR というのがあるので、もしかしたら ${BULLET_ROOT_DIR}/${BULLET_INCLUDE_DIR} のように利用することを想定しているのかもしれないということは考えた。
しかし、そうではないようだ。
なぜなら UseBullet.cmake は次のようになっているからだ。

#                                               -*- cmake -*-
#
#  UseBullet.cmake
#


add_definitions     ( ${BULLET_DEFINITIONS} )
include_directories ( ${BULLET_INCLUDE_DIRS} )
link_directories    ( ${BULLET_LIBRARY_DIRS} )

UseBullet.cmake をどうやって利用するのかは分かっていないのだけど、明らかなことがある。
それは BULLET_INCLUDE_DIRS をそのまま include_directories に渡せばOKだということを想定していることだ。
しかし、実際にそれをやっても BULLET_INCLUDE_DIRS は中途半端なパスなので、当然うまくいかない。

ということで、モジュールモードでもコンフィグモードでもうまくいかない。
おそらく何か見落としていることがあるのだろう。
cmakeをちゃんと訓練したことがなく、行き当りばったりで使ってきたので、欠けているものがあるのだろう。
Bulletの方が間違っているという可能性はあまりないだろう。
そろそろちゃんと訓練しないとなと思う次第。
当面Bulletを利用する間は、手動で設定することにするとする。

2022年3月11日 (金)


C++ Game Development By Example 第10章

テクスチャ。
Bulletの導入。

Bulletはなかなか厄介だ。
Solusのパッケージマネージャーeopkgでインストールできる。

$ sudo eopkg install bullet3-devel

これで試してみると、普通にリンクして実行するとメモリの確保、解放で死んでしまう。
ソースを取ってきてビルドすることにした。
ソースのダウンロードにも、ビルドにも結構時間がかかる。
make testもパスするし、exampleも動作する。
しかし、exampleに含まれるHelloWorldをコピーして、自前のCMakeLists.txtに最小限の設定を書いてビルドすると、やはり死ぬ。

App_HelloWorld: malloc.c:2539: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
fish: Job 1, './App_HelloWorld' terminated by signal SIGABRT (Abort)

Bulletのソースに含まれるCMakeLists.txtを調べていくと、どうも次のような記述が隠されているようだった。

target_compile_definitions(App_HelloWorld PRIVATE "-DBT_USE_DOUBLE_PRECISION")

これを追加してやると、死なずに動いた。
しかし、理由がまったく分からない。

2022年3月10日 (木)


C++ Game Development By Example 第7章まで読み終えた

なかなか良かった。
でき上ったゲームは今のままではまったく面白くない。
少し調整すれば遊べるものになるかもしれない。
次からはOpenGLを使ってゲームを作っていくようだ。

C++ Game Development By Example 第9章まで読み終えた

OpenGLの基礎。
結構慣れてきた。

2022年3月9日 (水)


Spacemacsのsmartparens-mode

C++のコードを書いていると、意図せずOFFになってしまう現象。
どうもスニペットを挿入するタイミングで発生するようだ。
その都度、本当にOFFになってしまっているかを確認してから SPC t p (toggle-smartparens) を実行しないといけない。
非常に煩わしい。
yasnippetのバグらしい
簡単な解決策が提案されている。
smartparens-modeをOFFにして、electric-pairs-modeをONにするという方法。
C++の場合だけそうすることにした。
dotspacemacs/user-configでフックに書いた。

(add-hook 'c++-mode-hook 'my-c++-hook)
(defun my-c++-hook ()
  ;; ...
  (smartparens-mode 0)
  (electric-pair-mode 1))

Emacsだったらこの書き方で問題ないのだろうけど、Spacemacsではどうするのが良いのか分かってない。
一応ちゃんと機能している。

2022年3月8日 (火)


暖かくなってきた

昼御飯は外で食べられるくらい暖かい。
まだ家の回りには雪がどっさり残っている。
もう積もることはないだろう。
あとは融けるだけだ。

2022年3月7日 (月)

曇り、雨

web hosting

日本だとレンタルサーバーと呼ばれるのが普通だけど、英語圏では web hosting と呼ばれるようだ。
サーバーを借りているというと大げさな感じがする。
どちらかというとWebサイトを置いているだけというニュアンスがあり、そのほうがしっくりくる。
少し調べて、Infinity Freeを利用してみることにした。
無料プランでSSLが使えるというのが決め手になった。
サイトの開設まではすぐだった。
設定を終えてから最大72時間かかると書かれていたが、10分も待たずにアクセスできるようになった。
SSLの設定をしてから、httpsのURLにアクセスできるようになるまでは少し時間がかった。
大体1時間くらいだろうか。
それでも十分早かったといえる。
これで念願のhttpsのサイトを持つことができた。
スターサーバーフリーも良かったのだけど、これからはInfinity Freeの方を更新していこうと思う。

https://waterbox.epizy.com/

ちょっと気掛りなのは、何も考えずに waterbox という名前にしたら、ちょっと wandbox に似てしまっていることだ。
誤解を招かないか、というのは考え過ぎだろう。

あとスターサーバーでは、3月31日までセールをやっていて、有料プランがかなり安くなっている。
もしかしたらそっちを使うようにするかもしれない。

2022年3月6日 (日)

曇り、雨

C++ Game Development By Example (Packt) を読み始めた

昨日読み終えたLearn OpenGLの、関連するタイトルに挙がっていた。
ちょっとだけ見てみると、なかなか良さそうなので読んでみることにした。
SFMLを使った2Dゲーム、OpenGLを使ったゲーム、Vulkanを使ったゲームと続いていくようだ。
ゲームプログラミングの入門には良くある進め方だ。
WindowsとMacに対応している。
正式には対応して
コーディングスタイルは、多くのゲームプログラミングの本と同じように、かなり初歩的でストレートなものだ。
あまり気にしないことにする。
今は6章の途中で、2Dゲームを作り始めたところ。
なかなか良い感じだ。

最近本しか読んでない

読まないよりは読んだ方がいい。
しかし、何か別のこともしたい。

Spacemacsのsmartparensが不意に無効になってしまう

smartparensとは、「(」や「"」などをタイプしたとき、自動で対応する閉じの「)」や「"」を補ってくれる機能だ。
とても快適で、だいたいONにしておきたい。
C++のコードを書いていると、括弧の入り組んだところで、なぜかsmartparensがOFFになってしまう。
特にラムダ式のところなどでよく(必ず?)発生する。
その都度 SPC t p でONにし直さないといけなくて、思考が中断される。
なんとかならないものだろうか。

2022年3月5日 (土)

曇り

Learn OpenGL 読んでる

この本はWebのチュートリアルを元にしているようだ。

  • https://learnopengl.com/
  • https://open.gl/

    特に、learnopenglの方の内容からソースコードをそのまま持って来ているようなところもある。
    Chapter 4のライティングのところはそうだった。
    テキストはそのまんまということではない。
    より簡単な説明になっている。
    詳細は上のURLのサイトを確認せよ、などの指示が随所にある。

Learn OpenGL 読み終えた

良い本とはいえないけど、なかなか勉強になった。
コードをどのように書くかに重点を置いている。
詳細な解説はほとんどない。
数式も一切出てこない。
とりあえず動かして体験してみることで、経験値を稼ぐといった趣きだ。
ちょうどそういうのを求めていたので、読んで良かった。

実は隠しチャプターが用意されていてる。
まだそれは読んでいない。

2022年3月4日 (金)


Learn OpenGL という本

SuperBibleを一旦離れて、PacktのLearn OpenGLに手を付けている。
Chapter 3まで読み終えた。
本当に初歩的な内容だ。
この本だけではとても十分に理解することは不可能だろう。
とりあえず動かして体験してみるといった程度だ。
SuperBibleがいかに詳細に書かれているかが分かる。
しかし、詳細なことは、学習においては負荷になることもある。
いったんLernの方で感覚を掴んでからという使い方をすれば、良い学習効果が得られそうだ。

2022年3月3日 (木)

雨、曇り

皮膚科に行ってきた

疣の治療。
もう何回目か忘れてしまった。
去年12月から通っている。
もう直ってるように見えるのだが、まだダメなんだろうか。

Modern C++ Programming Cookbook 第10章 読み終えた

パターンやイディオムの章。
特に目新しいものはなかった。
おさらいといったところ。

これでこの本はコンプリートだ。
まだ全然身に付いてはいない。
同著者の Modern C++ チャレンジ を読む資格は得ただろう。

第2版が出ていて、そちらはC++20もカバーしている。
今度差分だけ回収しておくことにする。

Optimized C++ を読み始めた

1章と2章を読んだ。
何か著者の最適化に対する執念が伝わってくるような文章だ。

Modern C++ チャレンジ を読み始める

別に急いで読む必要はないので、1日1問くらいのペースでやってこう。
100問あるから3ヶ月ちょっとで終わるはず。

2022年3月2日 (水)

曇り

Modern C++ Programming Cookbook 第8章 読み終えた

最後の一つ残っていたレシピを終えた。
並列なmap(std::mapではない。LispやHaskellなどのmapを真似たもの)と、foldのサンプル。
このサンプルだけでは、実際に開発で使えるまでには届かない。
もっと訓練が必要だ。

Modern C++ Programming Cookbook 第9章 読み終えた

色々なトピック。
その一つにスマートポインタのレシピがあった。

以前、ブロック崩しでやったNodeクラスで、スマートポインタを採用するとしたら、どうするのが良いか、というのを検討してみた。
そのときは、親ノードはunique_ptrで子ノードを所有して、子ノードは生ポインタで親ノードへの参照を保持するというのを考えた。
これはあまり良くない。
もし、子ノードが親ノードより長生した場合、子ノードは死んだ親ノードへの参照を保持することになる。
それよりも、親はshared_ptrで子ノードを所有して、子はweak_ptrで親ノードへの参照を保持するというのが正解のようだ。

enable_shared_from_thisというのを知った。
これも使えそうだ。

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class Node : public enable_shared_from_this<Node> {
 public:
  Node(weak_ptr<Node> parent = weak_ptr<Node>{}) : parent_{parent} {}
  virtual ~Node() { cout << "~Node():" << this << '\n'; }
  Node(Node const &) = delete;
  Node &operator=(Nodec const &) = delete;

  auto add_child(shared_ptr<Node> child);
  auto walk_foo() const -> void;

 private:
  virtual void foo() const {}
  vector<shared_ptr<Node>> children_;
  weak_ptr<Node> parent_;
};

auto Node::add_child(shared_ptr<Node> child) {
  child->parent_ = weak_from_this();
  children_.push_back(child);
}

auto Node::walk_foo() const -> void {
  foo();
  for (auto const c : children_) {
    c->walk_foo();
  }
}

class IntNode : public Node {
 public:
  IntNode(int x, weak_ptr<Node> parent = weak_ptr<Node>{})
      : value_{x}, Node{parent} {}

 private:
  void foo() const override { cout << "IntNode(" << this << "):" << value_ << '\n'; }
  int value_;
};

auto main() -> int {
  auto root = make_shared<Node>();

  auto n1 = make_shared<IntNode>(10);
  root->add_child(n1);

  auto m1 = make_shared<IntNode>(99);
  n1->add_child(m1);

  root->walk_foo();
}

試しに、書いたらこんな感じになった。
関数の引数にいちいちweak_ptrと出てくるのが煩わしい。

2022年3月1日 (火)

曇り、雨

Modern C++ Programming Cookbook 第8章 読み終えた

…のつもりが、終わらなかった。
あとはレシピ一つ。
threadとtask(async、feature)のサンプルと計測のみ。

Created: 2024-02-07 水 06:51

Emacs 29.1 (Org mode 9.6.6)

Validate