访问前n个可变参数函数参数

ura*_*ray 6 c++ templates constructor variadic-templates c++11

我有以下代码:

template<size_t sz,typename T=float> class Vec{
    T v[sz];    
    Vec(const T& val,const T&... nv){
        //how do i assign `sz` number of first arguments into `this->v` array
    }
}
Run Code Online (Sandbox Code Playgroud)

我想创建构造函数,接收通用数量的构造函数参数,并将第一个sz参数数分配给成员变量v

我想做的是能够做到这样: Vec<3> var(1.0,2.0,3.0);

Ant*_*ams 1

这是可能的,但很复杂。这是一些执行此操作的代码。也许可以消除该holder类型,但我将其作为练习留给读者。这已经用 g++ 4.6 进行了测试。

#include <iostream>
#include <typeinfo>

template<size_t ... Indices> struct indices_holder
{};

template<size_t index_to_add,typename Indices=indices_holder<> >
struct make_indices_impl;

template<size_t index_to_add,size_t...existing_indices>
struct make_indices_impl<index_to_add,indices_holder<existing_indices...> >
{
    typedef typename make_indices_impl<
        index_to_add-1,
        indices_holder<index_to_add-1,existing_indices...> >::type type;
};

template<size_t... existing_indices>
struct make_indices_impl<0,indices_holder<existing_indices...> >
{
    typedef indices_holder<existing_indices...>  type;
};

template<size_t max_index>
typename make_indices_impl<max_index>::type make_indices()
{
    return typename make_indices_impl<max_index>::type();
}

template<unsigned index,typename ... U>
struct select_nth_type;

template<unsigned index,typename T,typename ... U>
struct select_nth_type<index,T,U...>
{
    typedef typename select_nth_type<index-1,U...>::type type;

    static type&& forward(T&&,U&&... u)
    {
        return select_nth_type<index-1,U...>::forward(static_cast<U&&>(u)...);
    }
};

template<typename T,typename ... U>
struct select_nth_type<0,T,U...>
{
    typedef T type;

    static type&& forward(T&&t,U&&...)
    {
        return static_cast<T&&>(t);
    }
};

template<unsigned index,typename ... U>
typename select_nth_type<index,U...>::type&& forward_nth(U&&... u)
{
    return static_cast<typename select_nth_type<index,U...>::type&&>(
        select_nth_type<index,U...>::forward(
            static_cast<U&&>(u)...));
}

template<size_t sz,typename T=float> struct Vec{
    struct holder
    {
        T data[sz];
    };

    holder v;

    template<typename ... U>
    struct assign_helper
    {
        template<size_t... Indices>
        static holder create_array(indices_holder<Indices...>,Vec* self,U&&... u)
        {
            holder res={{static_cast<T>(forward_nth<Indices>(u...))...}};
            return res;
        }
    };

    template<typename ... U>
    Vec(U&&... u):
        v(assign_helper<U...>::create_array(make_indices<sz>(),this,static_cast<U&&>(u)...))
    {}
};

int main()
{
    Vec<3> v(1.2,2.3,3.4,4.5,5.6,7.8);

    std::cout<<"v[0]="<<v.v.data[0]<<std::endl;
    std::cout<<"v[1]="<<v.v.data[1]<<std::endl;
    std::cout<<"v[2]="<<v.v.data[2]<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)