Rokiのチラ裏

学生による学習のログ

エイリアステンプレート

なんだか忘れてしまっていたのか、知らなかったのか分からないが、便利なのでメモメモ。

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;
}

分りやすい上に使いやすく、幅が広がりんぐだ。