言語仕様により std::initializer_list はコピーした時にリストの値自体のコピーはしない
いわゆるシャローコピーである事が規定されている。
そのため、MSpellDrsDataのコンストラクタが終了した時に引数drsに構築されたリストの値を
保持する領域は解放されており、コンストラクタで生成したラムダ式にコピーキャプチャした
std::initializer_list が指しているリストの値の領域は不正な領域となる。
結果として update_smart_learn の引数が想定していないものとなり、 smart_learn が
正常に機能しない。
ラムダ式にキャプチャする時に std::vector オブジェクトに初期化キャプチャすることで
この問題を回避するように修正する。
}
MSpellDrsData::MSpellDrsData(std::initializer_list<drs_type> drs)
- : execute([drs](auto player_ptr, auto m_idx) {
+ : execute([drs = std::vector<drs_type>(drs)](auto player_ptr, auto m_idx) {
for (auto &d : drs) {
update_smart_learn(player_ptr, m_idx, d);
}