Boost 1.53で、maked_sharedの配列対応およびshared_ptrの配列対応が追加されました。

#include <boost/smart_ptr/make_shared_array.hpp>
 
using boost::make_shared;
 
int main()
{
  // 4要素の配列
  // p0はboost::shared_ptr<int[]>型
  auto p0 = make_shared<int[]>(4);
 
  // 4要素の配列
  // p1はboost::shared_ptr<int[4]>型
  auto p1 = make_shared<int[4]>();
 
  // 初期化リスト
  // p2はboost::shared_ptr<int[]>型
  auto p2 = make_shared<int[]>({0, 1, 2, 3});
 
  // 初期化リスト
  // p3はboost::shared_ptr<int[4]>型
  auto p3 = make_shared<int[4]>({0, 1, 2, 3});
}

上記コードのコメントに書いたように、配列版make_sharedが返す型は、boost::shared_ptr<T[]>やboost::shared_ptr<T[N]>型になります。boost::shared_array<T>ではありません。まだ、きちんと使ったことはありませんが、[]演算子が使えるなど、使い勝手はboost::shared_arrayとそう変わりなさそうな感じがします。

このほかにも、初期値(コンストラクタに渡す実引数)を指定できるものもあります。

#include <iostream>
#include <complex>
#include <boost/range/iterator_range.hpp>
#include <boost/smart_ptr/make_shared_array.hpp>
 
using boost::make_shared;
using boost::make_iterator_range;
 
int main() 
{
  // 4要素で、各要素はstd::complex<double>(1.0, 1.0)になる。
  // pfはboost::shared_ptr<std::complex<double>[]>型
  auto pc1 = make_shared<std::complex<double>[]>(4, 1.0, 1.0);
 
  // 4要素で、各要素はstd::complex<double>(2.0, 2.0)になる。
  // pfはboost::shared_ptr<std::complex<double>[4]>型
  auto pc2 = make_shared<std::complex<double>[4]>(2.0, 2.0);
 
  for (auto x : make_iterator_range(pc1.get(), pc1.get() + 4))
  {
    std::cout << x << std::endl;
  }
 
  std::cout << "----" std::endl;
 
  for (auto x : make_iterator_range(pc2.get(), pc2.get() + 4))
  {
    std::cout << x << std::endl;
  }
}

new[]と同じで、要素数は覚えてくれません(boost::shared_arrayと同じです)。そのため、for文で回すところが少しダサいのはご愛嬌なのです。なお、shared_ptr<T[N]>と要素数指定のある型の場合は、[]演算子でのアクセスの際に範囲チェックが入るそうです。

このほか、allocalte_sharedの配列版、2次元配列への対応もあるようです。

正直言って、std::shared_ptrがあるから、もうboost::shared_ptrは要らないかと思っていました。しかし、こんな便利なものが入ったら、まだまだboost::shared_ptrも使いたくなりますね。

参考: make_shared and allocate_shared(Boost 1.53のリファレンス)

2012年3月16日追記: 固定長配列のゼロ初期化 make_shared<int[]>の例を追加。


スポンサード リンク

この記事のカテゴリ

  • ⇒ 配列版boost::make_shared (Boost 1.53)