模板专业化可能是最简单的方法。
template <typename T>
struct functionize;
template <typename... Ts>
struct functionize<std::tuple<Ts...>> {
using type = std::tuple<std::function<void(Ts)>...>;
}
using MyTuple = std::tuple<int, double, char>;
using MyTupleFunctionized = typename functionize<MyTuple>::type;
为了使其更通用,您可以接受模板模板参数以应用于包。
template <typename Tuple, template <typename> typename Component>
struct transform_tuple;
template <typename... Ts, template <typename> typename Component>
struct transform_tuple<std::tuple<Ts...>, Component> {
using type = std::tuple<Component<Ts>...>;
}
using MyTuple = std::tuple<int, double, char>;
using MyTransformedTuple = typename transform_tuple<MyTuple, std::shared_ptr>::type;
更通用的解决方案最适合c++17 或更高版本。在此之前,它只会匹配具有恰好 1 个参数的模板。在c++17 之后,它还可以匹配std::vector 之类的东西,它有两个模板参数,而第二个模板参数有一个默认参数。
编辑:
正如 @Jarod42 和 @Caleth 在 cmets 中所指出的,我们可以在这方面进行更多改进。
template <typename Tuple, template <typename...> typename Component>
struct transform_tuple;
模板模板参数的参数包允许我们从c++11 传入类似std::vector 的内容并转发。如果我们想要传递混合类型和非类型参数的东西,比如std::array,那只会留下问题。
我们可以通过使用模板别名来部分解决这个问题。
template <typename T>
using FixedArray10 = std::array<T, 10>;
using MyTransformedTuple = typename transform_tuple<MyTuple, FixedArray10>::type;