beet's soil

競プロのことなど

多重vectorを可変引数テンプレートで


すいばか さんに圧倒的感謝🙏🙏😭🙏🙏

以下C++ のコード

すいばかさん版:型は最後の引数で決まる

template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}

template<typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}

型をtemplateで指定する版

template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

グローバルでauto関数が定義できるの知らなかった(ラムダだけだと思い込んでた)

eiyaさんの N次元配列を同じ値で埋めるテンプレ2 を参考にするとfillもできる
N次元配列を同じ値で埋めるテンプレ2 - 永夜の記録

template<typename T,typename V>
typename enable_if<is_class<T>::value==0>::type
fill_v(T &t,const V &v){t=v;}

template<typename T,typename V>
typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t,const V &v){
  for(auto &e:t) fill_v(e,v);
}

githubのリンク
https://github.com/beet-aizu/library/blob/master/vec.cpp

auto dp=make_v<int>(4,h,w);
fill_v(dp,0);

みたいに使える

これでやっと

vector<vector<vector<int> > > dp(4,vector<vector<int> >(h,vector<int>(w)));

から解放される…!


2019/03/29追記

わかるなあ わかるので ついでにコンストラクタ呼ぶようにするか

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value!=0>::type
fill_v(U &u,const V... v){u=U(v...);}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value==0>::type
fill_v(U &u,const V... v){
  for(auto &e:u) fill_v<T>(e,v...);
}

↓みたいな使い方ができる

  auto vt=make_v<tuple<int, double> >(3,3);
  fill_v<tuple<int, double> >(vt,2,0.5);
  cout<<get<0>(vt[0][0])<<endl;
  cout<<get<1>(vt[2][2])<<endl;