通过一个例子可以更好地解释:
template <typename T1, typename T2>
struct OnePair
{
using TupleOfArgs = std::tuple<T1, T2>;
using TupleOfPairs = std::tuple<std::pair<T1, T2>>;
};
template <typename T1, typename T2, typename T3, typename T4>
struct TwoPairs
{
using TupleOfArgs = std::tuple<T1, T2, T3, T4>;
using TupleOfPairs = std::tuple<std::pair<T1, T2>, std::pair<T3, T4>>;
};
template <typename... Args>
struct NPairs
{
using TupleOfArgs = std::tuple<Args...>;
// using TupleOfPairs = ???
};
OnePair 定义一个具有一对的元组。 TwoPairs 定义了一个包含两对的元组。
如何在 NPairs 中定义 TupleOfPairs,以便将参数包转换为 std::tuple 对?
是否可以使用 std 库来实现这一点?也许用 boost::mpl ?
两个答案,都很好。 @chris 使用迭代方法,而 @aschepler 使用递归解决方案。 就我个人而言,我发现递归解决方案更容易遵循。
最佳答案
您可以使用熟悉的索引序列技巧,但大小减半 ( live example ):
static constexpr auto get_tuple() {
constexpr auto N = sizeof...(Args);
static_assert(N%2 == 0);
using ArgsTuple = std::tuple<Args...>;
auto impl = []<std::size_t... Is>(std::index_sequence<Is...>) {
return std::tuple<
// Is goes from 0 to N/2, representing Ith pair
std::pair<std::tuple_element_t<Is*2, ArgsTuple>, std::tuple_element_t<Is*2 + 1, ArgsTuple>>...
>{};
};
return impl(std::make_index_sequence<N/2>{});
}
using TupleOfArgs = decltype(get_tuple());
如果您没有 C++20,则必须将 lambda 扩展为函数,而不是能够使用良好的内联索引序列扩展,但核心仍然可以运行。使用类型列表而不是 std::tuple 可能会更干净一些,但它是可行的。
关于c++ - 如何将 Parameter Pack 转换为 std::tuple 之外的其他内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61335122/