用于几个组件的指数技巧

pre*_*eys 5 c++ templates indices variadic-templates c++11

考虑这个完全有效的代码:

#include <type_traits>

template <typename T, typename IndexPack> struct Make;

template <typename T, template <T...> class P, T... Indices>
struct Make<T, P<Indices...>> {
    using type = P<(Indices+1)..., (-3*Indices)..., (Indices-1)...>;
};

template <int...> class Pack;

int main() {
    static_assert (std::is_same<Make<int, Pack<1,2,3,4>>::type, 
        Pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>>::value, "false");
}
Run Code Online (Sandbox Code Playgroud)

我真正想要的输出是什么

Pack<2,-3,0, 3,-6,1, 4,-9,2, 5,-12,3>
Run Code Online (Sandbox Code Playgroud)

而不是Pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>.我第一次尝试

using type = P<(Indices+1, -3*Indices, Indices-1)...>;
Run Code Online (Sandbox Code Playgroud)

但编译器简单地将其理解为无用的逗号运算符.得到我想要的东西的理想语法是什么?如果没有这样的语法,最简洁的方法是什么,请记住,使用Indices3次只是一个例子(我们可能想要使用它超过3次).请不要告诉我,我必须写一个助手来提取单个包,然后"交织"所有元素.这种噩梦般的方法不是最好的解决方案(只有当我们确切地知道要提取多少个包时,这样的解决方案才有效).

会定义

template <typename T, template <T...> class P, T I>
struct Component {
    using type = P<I+1, -3*I, I-1>;
};
Run Code Online (Sandbox Code Playgroud)

不知怎的?对此进行扩展?

Col*_*mbo 4

是的,您可以递归连接:

template <typename, typename, typename> struct Concat;

template <typename T, template <T...> class P, T... A, T... B>
struct Concat<T, P<A...>, P<B...>> {
    using type = P<A..., B...>;
};

template <typename T, typename IndexPack> struct Make;

template <typename T, template <T...> class P, T... I, T F >
struct Make<T, P<F, I...>> {
    using type = typename Concat<T,
                                 typename Make<T, P<F>>::type,
                                 typename Make<T, P<I...>>::type>::type;
};

template <typename T, template <T...> class P, T I>
struct Make<T, P<I>> {
    using type = P<I+1, -3*I, I-1>;
};
Run Code Online (Sandbox Code Playgroud)

演示