请允许我提供一些我的问题的背景:
我有一项大学作业,为我提供了一个名为 StringList 的课程。该类负责许多字符串操作,例如inserting,removing等。这些方法的函数签名的一些示例如下所示:
void insert_before(int index, const std::string &s)
{
//...
}
// Must be undoable
void remove_bofore(int index)
{
//...
}
void undo()
{
// Attempts to revert back to the last operation
}
这项作业要求我实现一个 stack,并能够提供 undo() 操作,该操作本质上是反转之前发生的功能。例如,如果某些代码决定调用名为 insert_before() 的类方法,则 StringList 类必须使用堆栈来提供通过删除插入的字符串操作来恢复的能力。
实现堆栈似乎是一项相当琐碎的任务,但主要问题是试图找出如何以最简单的方式实现 undo() 操作。我最初的想法是创建一个 Node 结构,除了标准的下一个指针(允许它引用其他节点)之外,还将包含一个 函数指针 变量,如下所示:
// Used in singly linked list stack
struct Node
{
Node* next;
void(*function)();
};
这有助于存储需要调用的所需函数,以便 undo() 先前执行的操作。这是通过保存上次执行的完全相反的操作来完成的。例如,如果调用 insert_before() 方法,那么它的行为将如下所示:
void insert_before(int index, const std::string &s)
{
// Perform the insertion...
stack.push(
remove_before(index) // Storing the function that needs to be called by undo()...
);
}
我采用这种方法面临的主要问题是我不确定是否允许我们在一个公共函数指针下存储不同的函数签名。函数指针显然需要一个返回类型为 void 签名且参数为 void 类型的函数。但是,需要存储在其中的每个函数都有不同的签名,而这只是 2 种方法,还有更多方法。
我可以继续为每个方法类型创建一个函数指针,但我认为为每个方法类型创建这么多不同的函数指针不是一个好主意。
那么,我该怎么办呢?我的意思是...是否可以将所有这些都存储在一个函数指针下?或者我还能用这个做些什么吗?
您不需要不同的签名。签名始终是
void(StringList &)
,或类似的东西。 undo()
不接受任何参数,因此需要撤消的任何其他参数都需要烘焙到您要存储的函数中。
使用捕获 lambda:
stack.push([index](StringList &list)
{
list.remove_before(index);
});
由于函数指针无法指向捕获 lambda,请使用
std::function
代替。