auto_ptrのconstについて考えていた

std::map
とかやっていたところ、これをメンバに持つクラスのデストラクタでここに追加された要素を全部deleteしてあげるのを忘れてメモリリークがでてたのですよ。そこで、
std::map >
としてみたわけですがこれがコンパイルできない。原因は、std::auto_ptrがconst auto_ptrを引数にとるコピーコンストラクタをもってない → mapの中身のデータであるところのpairは当然のことながらconst付きの参照を受けるコピーコンストラクタを宣言してる。結果 × というわけでした。

原因がわかったのでauto_ptrをいじって、const auto_ptrを受け取るコピーコンストラクタを宣言してしまえばいいじゃんとなるわけですが、auto_ptrというのは自分が消されようとしたときに内包するポインタをdeleteしてやらないといけないので、「所有権」なるものを中にもっているわけなのですが、普通にコピーする場合はコピー元から所有権を剥奪して、コピー先にあたる自分にその所有権を移さないといけない。それがauto_ptrのauto_ptrたる由縁なわけなのですが、普通にこのクラスにconstが付いてくれば言語仕様的には当然コピー元の「所有権」を剥奪なんてことはできないようにデフォルトではなっているわけです。それをconst_castして無理矢理「所有権」を剥奪してしまうのはconstのついたauto_ptrの使われかたとして、auto_ptrにconstを付けた側としては正しいものなのだろうかと心配したわけです。どういうときにauto_ptrにconstが付くんだろうか?constは通常では読み取り専用みたいな意味があるだろうが、それがauto_ptrに付けられたらどう振舞うべきなのか?

問題は結局のところ絶対に所有権を剥奪されないということを意図してconstをauto_ptrにつける奴がいるのかということになってくるわけなのだけれども、そんなやつはいないと結論したいわけです。大抵はそれまで普通に*を使っていたところをauto_ptrを使うようにに切り替えるような使い方をするわけで、その移行がスムーズに行われるためにoperator->()とかoperator*()が用意されているんじゃないでしょうか。それと同様にconstも、普通に*についていたときと同じにポインタの指す先が変更されないということを保証するという意味でとらえるのが適当なのではと思うわけです。つまりconst auto_ptr イコール auto_ptr です。少なくとも、pairで宣言しているconstをとるコンストラクタはそういうことを想定しているはずです。

で、const auto_ptr イコール auto_ptrとなるようにauto_ptrは実装されるべきだと思うわけだったのですが、それをいちいち自分で書くのはめんどくさいんでstd::auto_ptr使えねーなということで単純に使うのをやめた。