我正在编写一种自定义解释语言,它使用后进先出堆栈进行数据操作。在两个地方,我需要能够从存储在堆栈上的值构造一个元组。原则上,此代码将如下所示:
template<typename... Args>
[[nodiscard]] inline std::tuple<Args...> popTupleFromStack(Stack& stack)
{
return { stack.Pop<Args>()... };
}
但是,栈的后进先出顺序有一个基本问题:初始化器列表顺序指示调用从左到右发生,这意味着它实际上会尝试以完全相反的顺序弹出元素。有什么简单的方法可以颠倒这个顺序吗?
我知道折叠表达式允许您指定向左或向右折叠,但当您需要使用结果初始化对象时,似乎不能使用折叠表达式。
我的闭包是手动指定元组中可能的参数数量的重载:
template<typename Arg0>
[[nodiscard]] inline std::tuple<Arg0> popStackTuple(Stack& stack)
{
return { stack.Pop<Arg0>() };
}
template<typename Arg0, typename Arg1>
[[nodiscard]] inline std::tuple<Arg0, Arg1> popStackTuple(Stack& stack)
{
Arg1 arg1 = stack.Pop<Arg1>();
Arg0 arg0 = stack.Pop<Arg0>();
return { arg0, arg1 };
}
但这显然限制了我可以支持的参数数量,并且/或者导致了许多“不必要的”代码。用现代的C++做不到这似乎是一件微不足道的事情(我已经准备好了所有的东西,如果有什么不同的话,包括C++20 )。
发布于 2021-05-23 14:15:16
之后,您可以反转元组
template <std::size_t ... Is, typename Tuple>
auto reverse_tuple_impl(std::index_sequence<Is...>, Tuple& tuple)
{
using res_type = std::tuple<std::tuple_element_t<sizeof...(Is) - 1 - Is, std::decay_t<Tuple>>...>;
Is, std::decay_t<Tuple>>>;
return res_type(std::get<sizeof...(Is) - 1 - Is>(tuple)...);
}
template <typename ... Ts>
auto reverse_tuple(std::tuple<Ts...>& tuple)
{
return reverse_tuple_impl(std::index_sequence_for<Ts...>(), tuple);
}
发布于 2021-05-23 15:45:13
不是很大的进步但是..。如果可以使用C++20,那么可以将帮助函数嵌入到reverse_tuple()
中
template <typename ... Ts>
auto reverse_tuple (std::tuple<Ts...> & tuple)
{
return [&]<std::size_t ... Is> (std::index_sequence<Is...>)
{ return std::make_tuple(std::get<sizeof...(Is)-1u-Is>(tuple)...); }
(std::index_sequence_for<Ts...>{});
}
https://stackoverflow.com/questions/67660638
复制相似问题