Boost 1.53からのshared_ptr<T[]>やshared_ptr<T[N]>は配列でないshared_ptrと相互に変換できるのが便利です。これはshared_arrayではできませんでした。

// bufferはboost::shared_ptr<char[]>型
// boost::shared_ptr<char[]> buffer(new char[size]);としても可
auto buffer = boost::make_shared<char[]>(size);
auto p = boost::reinterpret_pointer_cast<binary_data>(buffer);

今まではこのようにする必要がありました。boost::shared_arrayとboost::shared_ptrとの変換が用意されていないため、shared_ptrに一工夫してnew[]で得たポインタを格納する必要があったのです。

boost::shared_ptr<char> buffer(
  new char[size], boost::checked_array_deleter<char>());
// あるいはこちら (C++11)
// boost::shared_ptr<char> buffer(
//   new char[size], std::default_delete<char[]>());
 
auto p = boost::reinterpret_pointer_cast<binary_data>(buffer);

そのような処理は、たとえばこういう風に可変長なデータ構造を扱う場合に使います。

#include <iostream>
#include <cstring>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/shared_array.hpp>
#include <boost/smart_ptr/make_shared_array.hpp>
//#include <boost/checked_delete.hpp>
 
struct binary_data
{
  int length;
  char data[1]; // ← こういうの!!!
};
 
int main()
{
  const char* source = "Quick brown fox ...";
  auto source_length = std::strlen(source);
 
  auto size = sizeof (binary_data) - 1 + source_length;
 
  // boost::shared_ptr<char> buffer(
  //   new char[size], boost::checked_array_deleter<char>());
  boost::shared_ptr<char[]> buffer = boost::make_shared<char[]>(size);
  auto p = boost::reinterpret_pointer_cast<binary_data>(buffer);
 
  p->length = source_length;
  std::memcpy(&p->data[0], source, source_length);
  for (int i = 0; i < p->length; ++i)
  {
    std::cout << p->data[i];
  }
  std::cout << std::endl;
}

余談ですが、C99以降だと、char data[];という構文があるんですよね。C++11にはやってきていないはずですが。

スポンサード リンク

この記事のカテゴリ

  • ⇒ 配列版shared_ptrと非配列版shared_ptrとの変換