考虑以下完全有效的代码:
#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");
}
我真正想要的输出是
Pack<2,-3,0, 3,-6,1, 4,-9,2, 5,-12,3>
而不是
Pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>
。我第一次尝试using type = P<(Indices+1, -3*Indices, Indices-1)...>;
但这只是编译器将其理解为无用的逗号运算符。得到我想要的是什么所需的语法?如果没有这样的语法,那么最干净的方法是什么,请记住,使用
Indices
3次只是一个示例(我们可能希望使用3次以上)。请不要告诉我,我必须编写一个助手来提取单个包装,然后“交织”所有元素。那种噩梦般的方法不可能是最好的解决方案(而且这种解决方案也只有在我们确切知道要提取多少个单个包装的情况下才有效)。将定义
template <typename T, template <T...> class P, T I>
struct Component {
using type = P<I+1, -3*I, I-1>;
};
以某种方式帮助?对此进行包装扩展吗?
最佳答案
是的,您可以递归连接:
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>;
};
Demo
关于c++ - 用于多个组件的索引技巧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29907927/