【发布时间】:2021-05-23 14:07:33
【问题描述】:
我正在编写一种自定义解释语言,它使用 LIFO 堆栈进行数据操作。在两个地方,我需要能够从存储在堆栈中的值构造一个元组。原则上,这段代码应该是这样的:
template<typename... Args>
[[nodiscard]] inline std::tuple<Args...> popTupleFromStack(Stack& stack)
{
return { stack.Pop<Args>()... };
}
但是,堆栈的 LIFO 排序存在一个基本问题:初始化列表顺序规定调用从左到右发生,这意味着它实际上会尝试以完全相反的顺序弹出元素.有什么简单的方法可以颠倒这个顺序吗?
我知道折叠表达式允许您指定左折叠或右折叠,但是当您需要使用结果初始化对象时,您似乎不能使用折叠表达式。
我的结局是手动为元组中的潜在参数数量指定重载:
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,如果有什么不同的话,我可以随意使用)。
【问题讨论】:
-
为什么不使用
dequeue而不是stack? -
@πάνταῥεῖ 堆栈不仅仅包含该元组中的元素。正如我所说,我几乎正在为基于字节码的语言(想想 Java)编写解释器,当我调用 popStackTuple 时,元组元素下方是大量其他数据,所以我不能只使用 PopFront。