【问题标题】:How to instantiate array of objects from template with running parameter如何使用运行参数从模板实例化对象数组
【发布时间】:2014-11-21 08:12:21
【问题描述】:

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

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 个元素,每个元素指向一个从模板创建的具有自己参数的对象实例。

【问题讨论】:

    标签: c++ arrays templates iterator


    【解决方案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

    【讨论】:

    • 不幸的是,我使用的是 gcc-4.7 不支持 -std=c++14 的 debian 7。
    • @hutorny here 是 C++11 实现
    • @hutorny 你可能还想在别名后面隐藏两个模板参数的类模板,比如template &lt;int N&gt; using W = Q&lt;N&gt;;,这样就没有人输入Q&lt;4, index_sequence&lt;4,8,0,100&gt;&gt;
    【解决方案2】:

    您可以使用以下内容:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多