boost::shared_ptrで少し不思議な挙動に出会いました。
// 下のコメントアウトを外すとコンパイルが通る。 // #define BOOST_SP_NO_SP_CONVERTIBLE #include <boost/shared_ptr.hpp> #include <boost/make_shared.hpp> class B {}; class B1 : public B {}; class B2 : public B {}; class D : public B1, public B2 { public: B* get(); }; int main() { boost::shared_ptr<D> d = boost::make_shared<D>(); boost::shared_ptr<B> b(d, d.getB()); } |
bの初期化で使用しているコンストラクタは、ポインタの値はd.getB()だけど参照カウントはdを共有するというものです。詳しい説明が今更ながらに Boost.SmartPointers を考える – 銀天随筆集の「応用的な使い方」にあります。
さて、これは特に問題ない(コンパイルエラーになるコードではない)と思うのですが、DからBへの変換が曖昧だということでエラーになってしまいました。これが遭遇した少し不思議な挙動です。
解決方法は、2つ見つけました。
1つは、上記ソースコードに書いてあるように、BOOST_SP_NO_SP_CONVERTIBLEを定義するという方法です。エラーメッセージに出力されたソースファイルboost/smart_ptr/detail/sp_convertible.hppを開いたところ、見つけました。
もう1つはboost::shared_ptr<void>を介す方法です。BOOST_SP_NO_SP_CONVERTIBLEの定義が望ましいエラーチェックまで無くしてしまうことを危惧するなら、こちらが良いと思います。
int main() { boost::shared_ptr<D> d = boost::make_shared<D>(); boost::shared_ptr<void> tmp = d; boost::shared_ptr<B> b(std::move(tmp), static_cast<B1*>(d.get())); } |
なお、単にアップキャストしたいだけならboost::shared_ptr<B> b = boost::static_pointer_cast<B1>(d);などとすれば大丈夫です、一応念のため。
スポンサード リンク |
この記事のカテゴリ
- C++ ⇒ boost::shared_ptrの少し不思議な挙動