C++ 如何使用运行参数从模板实例化对象数组

C++ 如何使用运行参数从模板实例化对象数组,c++,arrays,templates,iterator,C++,Arrays,Templates,Iterator,我将感谢您对以下简化示例的帮助: template<int N> struct Q { struct X { virtual int v() = 0; }; template<int i> struct Z : X { virtual int v() { return i; } }; Z<0> z1; /* ... */ Z<N-1> zN;

我将感谢您对以下简化示例的帮助:

template<int N>
struct Q {
    struct X {
        virtual int v() = 0;
    };
    template<int i>
    struct Z : X {
        virtual int v() { return i; }
    };
    Z<0> z1;
    /* ... */
    Z<N-1> zN;

    X * x[N] = { &z1, /* ... */ &zN };
};

Q<4> q;
模板
结构Q{
结构X{
虚拟int v()=0;
};
模板
结构Z:X{
虚拟int v(){return i;}
};
zz1;
/* ... */
锌;
X*X[N]={&z1,/*…*/&zN};
};
Q;
本例的最终目标是在q.x中创建N个元素,每个元素都指向一个对象实例,该对象实例是使用自己的参数从模板创建的
#include <utility>
#include <tuple>
#include <iostream>

template <int N, typename T = std::make_index_sequence<N>>
struct Q;

template <int N, std::size_t... Is>
struct Q<N, std::index_sequence<Is...>>
{
    struct X
    {
        virtual int v() = 0;
    };

    template <int i>
    struct Z : X
    {
        virtual int v() { return i; }
    };

    std::tuple<Z<Is>...> z;

    X * x[N] = { &std::get<Is>(z)... };
};

int main()
{
    Q<4> q;
    std::cout << q.x[0]->v() << std::endl;
    std::cout << q.x[1]->v() << std::endl;
}
#包括 #包括 模板 结构Q; 模板 结构Q { 结构X { 虚拟int v()=0; }; 模板 结构Z:X { 虚拟int v(){return i;} }; std::tuplez; X*X[N]={&std::get(z)…}; }; int main() { Q;
std::cout v()您可以使用以下命令:

namespace detail
{
    template <template <int> class Z, typename Seq> struct tuple_Z;


    template <template <int> class Z, std::size_t ... Is>
    struct tuple_Z<Z, std::index_sequence<Is...>>
    {
        using type = std::tuple<Z<Is>...>;
    };

    template <typename X, std::size_t N, typename Tuple, std::size_t ... Is>
    constexpr std::array<X*, N> make_X_Array(Tuple& t, std::index_sequence<Is...>)
    {
        return {{(&std::get<Is>(t))...}};
    }

}


template<int N>
struct Q {
    struct X {
        virtual int v() = 0;
    };
    template<int i>
    struct Z : X {
        virtual int v() { return i; }
    };

    Q() : Xs(detail::make_X_Array<X, N>(Zs, std::make_index_sequence<N>())) {}

    typename detail::tuple_Z<Z, typename std::make_index_sequence<N>>::type Zs;
    std::array<X*, N> Xs =
        detail::make_X_Array<X, N>(Zs, std::make_index_sequence<N>());
};
名称空间详细信息
{
模板结构元组;
模板
结构元组
{
使用type=std::tuple;
};
模板
constexpr std::array make_X_array(Tuple&t,std::index_序列)
{
返回{(&std::get(t))…};
}
}
模板
结构Q{
结构X{
虚拟int v()=0;
};
模板
结构Z:X{
虚拟int v(){return i;}
};
Q():Xs(detail::make_X_数组(Zs,std::make_index_序列()){}
typename细节::tuple_Z::typezs;
std::数组Xs=
detail::make_X_数组(Zs,std::make_index_sequence());
};

不幸的是,我使用的是debian 7,它的gcc-4.7不支持-std=c++14。@hutorny是c++11implementation@hutorny您可能还希望在别名后面隐藏两个模板参数类模板,例如使用W=Q;的
模板,这样就不会有任何类型的
Q