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

时间:2014-11-21 08:12:21

标签: 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;

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

Q<4> q;

此示例的最终目标是在q.x中创建N个元素,每个元素都指向使用自己的参数从模板创建的对象实例。

2 个答案:

答案 0 :(得分:1)

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

DEMO

答案 1 :(得分:0)

您可以使用以下内容:

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

Live example