seriruの技術屋ブログ

競技プログラミングやゲーム開発など技術に関することを発信します

make_vectorを自作する

std::vector<std::vector<std::vector<int>>> vec; みたいに型の中に何十も std::vector を書くのが死ぬほど面倒臭い。 ということで std::make_tuple のように型を指定して std::vector を返す関数を作りました。

make_vector

template <class Thead>
constexpr auto make_vector(Thead head)
{
  return std::vector<Thead>();
}

template <class THead, class ...Args>
constexpr auto make_vector(THead head, Args... tail) 
{
  return std::vector<decltype(make_vector(tail...))>();
}

次のように使います。

int main(){
  auto vec1 = slc::make_vector(1, 2); // vector<vector<int>>
  auto vec2 = slc::make_vector(1, '1'); // vector<vector<char>>
  int n = 3;
  auto v = slc::make_vector(1);
  for (int i = 0; i < n; ++i) {
    v.push_back(i);
  }

  vec1.push_back(v);

  for (int i = 0; i < n; ++i) {
    std::cout << vec1[0][i] << "\n";
  }
}

簡単な解説

make_vector は引数で指定してパラメータ分だけ次元を持つ std::vector を返します。
また、std::vector は最後に指定した型を持つベクトルになります。
つまり、引数自体には意味がありません。

今後の課題

  • 引数で指定したぶんの領域を確保できるようにする
  • 理想なのは make_vector<char>(10, 20, 30) // vector<vector<vector<char>>>(10, 20, 30) のように型引数を1つ取り、引数をあらかじめ確保したい要素数を指定できるようにすること。ただし、関数テンプレートは引数から型を推論できてしまうのと、どうやって型1つで可変長引数をとるのかがわからない。

今回のソース

github.com


いろいろ使えればいいな