エイリアステンプレート
なんだか忘れてしまっていたのか、知らなかったのか分からないが、便利なのでメモメモ。
template<class _Tp,class Allocator=std::allocator<_Tp>> std::vector<_Tp,Allocator> twice(std::vector<_Tp,Allocator> v) { for(typename std::vector<_Tp,Allocator>::iterator i=std::begin(v); i!=std::end(v); ++i)*i*=2; // なんだか視覚的にわかりにくい表現 // for(_Tp& e:v)e*=2; と書けば良い事は本題とズレるので置いておいて・・・ return v; // NRVO } void f() { std::vector<unsigned int> v{1,2,3,4,5}; v=twice(std::move(v)); for(std::add_lvalue_reference<std::add_const<decltype(v.front())>::type>::type e:v) // 演算子書けば良い事は本題とズレるので置いておいて・・・ std::cout<<e<<std::endl; }
typenameを書かなければならない。また::typeと書かなければならない。
これをエイリアステンプレートで予めラップしておく事で、視覚的に分かりにくい記述をなくしたり、複数のtype_traitsを合体させたりなど...夢が広がりんぐである。
template<class Tp,class _Allocator=std::allocator<Tp>> using vector_iterator=typename std::vector<Tp,_Allocator>::iterator; // alias template template<class _Tp,class Allocator=std::allocator<_Tp>> std::vector<_Tp,Allocator> twice(std::vector<_Tp,Allocator> v) { for(vector_iterator<_Tp,Allocator> i=std::begin(v); i!=std::end(v); ++i)*i*=2; return v; } template<class Tp> using add_lvalue_reference=typename std::add_lvalue_reference<Tp>::type; // alias template template<class Tp> using add_const=typename std::add_const<Tp>::type; // alias template template<class Tp> using add_const_lvalue_reference=add_lvalue_reference<add_const<Tp>>; // alias template void f() { std::vector<unsigned int> v{1,2,3,4,5}; v=twice(std::move(v)); for(add_lvalue_reference<add_const<decltype(v.front())>> e:v) std::cout<<e<<std::endl; for(add_const_lvalue_reference<decltype(v.front())> e:v) std::cout<<e<<std::endl; }
分りやすい上に使いやすく、幅が広がりんぐだ。