配列の参照を返す

C++で配列の参照を関数の返り値にするにはどうすればいいかを考えていた.
typedefで型を定義してやるとできるみたい.
arrayを使え,っていう話もある.

#include <iostream>
#include <iterator>
#include <array>
 
using namespace std;
 
struct A {
  A() : v_(1) {}
  A(int v) : v_(v) {}
  int v_;
  friend ostream & operator<<(ostream &o, const A x)
  {
    o << x.v_;
    return o;
  }
};
 
static const int N = 5;
 
struct B {
  static int k;

  typedef A bar[N];
  static bar& foo1()
  {
     static A array[N];
     for (int i = 0; i < N; ++i) array[i].v_ = k++;
     return array;
  }

  static A (&foo2())[N]
  {
     static A array[N];
     for (int i = 0; i < N; ++i) array[i].v_ = k++;
     return array;
  }

  static auto foo3() -> A (&)[N]
  {
     static A array[N];
     for (int i = 0; i < N; ++i) array[i].v_ = k++;
     return array;
  }

  static array<A,N> &foo4()
  {
     static array<A,N> ary;
     for (int i = 0; i < N; ++i) ary[i].v_ = k++;
     return ary;
  }
};

int B::k = 0;

template<class T> void show(const T &x);

template<class T>
void show(const T (&ary)[N])
{
  ostream_iterator<const A> couti(cout, ",");

  cout << ary << endl;
  copy(ary, ary+N, couti);
  cout << endl;
}

template<class T>
void show(const array<T,N> &ary)
{
  ostream_iterator<const A> couti(cout, ",");

  cout << ary.data() << endl;
  copy(ary.begin(), ary.end(), couti);
  cout << endl;
}

int main()
{
  A (&a1)[N] = B::foo1();
  show(a1);

  A (&a2)[N] = B::foo2();
  show(a2);

  A (&a3)[N] = B::foo3();
  show(a3);

  array<A,N> &a4 = B::foo4();
  show(a4);

  return 0;
}

追記

C++0xとBoostのarrayはちょっと違うらしい.
後で調べる.