C++
boost
convert
std
shared_ptr

boost::shared_ptr から std::shared_ptr へ変換する簡単な方法

More than 1 year has passed since last update.


方法

// std::shared_ptr

#include <memory>
// boost::shared_ptr
#include <boost/shared_ptr.hpp>

auto main() -> int
{
boost::shared_ptr< int > b = boost::shared_ptr<int>( new int( 123 ) );
std::shared_ptr< int > s = std::shared_ptr<int>( x.get(), [x] ( ... ) mutable { } );
}


検証


挙動の確認

「方法」の比較的簡潔なコードに、挙動の確認に適当なブロックスコープと std::cout などを仕込む例を紹介。

#include <iostream>

#include <memory>
#include <boost/shared_ptr.hpp>

using namespace std;

int main()
{
std::cout << "scope-A{\n";
{
std::cout << "scope-B{\n";
std::shared_ptr< int > s;
std::cout << "s = " << s << '\n';
{
std::cout << "scope-C{\n";
boost::shared_ptr< int > b = boost::shared_ptr< int >( new int( 123 ) );
std::cout << "b = " << b << '\n';
// 今回は解説の都合 b でキャプチャーすると紛らわしいので bc としてコピーキャプチャーする例示にします。
s = std::shared_ptr<int>( b.get(), [ bc = b ] ( ... ) mutable { std::cout << "reset bc in dtor lambda of s\n"; } );
std::cout << "s = " << s << '\n';
std::cout << "}scope-C\n";
}
std::cout << "s = " << s << '\n';
std::cout << "}scope-B\n";
}
std::cout << "}scope-A\n";
}

↑これをビルドして実行すると、↓こうなる。

scope-A{

scope-B{
s = 0
scope-C{
b = 0x1c595b0
s = 0x1c595b0
}scope-C
s = 0x1c595b0
}scope-B
reset bc in dtor lambda of s
}scope-A



  1. scope-A{: main 関数の関数スコープの始まり。


  2. scope-B{: std::shared_ptr< int > s が宣言されるブロックスコープの始まり。


  3. scope-C{: boost::shared_ptr< int > b が宣言、定義され、 scope-Bs に対して「変換」が行われるブロックスコープの始まり。


  4. }scope-C: オブジェクト b がスコープを外れ破棄されるタイミング。但し、「変換」が成功していれば bs のカスタムデリーターのラムダ式に bc としてコピーキャプチャーされているため、 b が破棄されても bcs のスコープで生存する「はず」というタイミング。


  5. }scope-B: 「変換」が成功していれば sscope-Bb と同じオブジェクトをこの時点までは間接参照できる「はず」の最後のタイミング。ここを超えるとオブジェクト s もスコープにより破棄されるので、 s のカスタムデリーターに仕込んだ bc の破棄出力が得られる「はず」のタイミング。


  6. }scope-A: ↑の(5)とこの(6)の間に s のカスタムデリーターによる bc の破棄出力が得られている「はず」のタイミング。

と、いうわけで、外部から観測する挙動としては意図通りに「変換」できている事がわかる。