二叉搜索树模板中带多参数函数指针的实现问题咨询
解决二叉搜索树中序遍历函数指针携带外部参数的问题
你的核心问题在于:
- 重载的
inOrder函数调用(*visit)(p->info)时,未传递需要的两个整数参数,不符合函数指针的签名要求; - 调用遍历函数时错误地直接执行
MyFunction(input1,input2),这会试图立即调用函数而非传递函数指针。
下面提供三种可行的解决方案:
方案一:修改遍历函数,直接传递外部参数
调整遍历函数的参数列表,让它接收需要的两个整数,再传递给visit函数:
遍历函数实现
template<class T> void BSTTemplate<T>::inOrder(Node<T>* p, void (*visit)(T&, int&, int&), int& input1, int& input2) const { if (p != nullptr) { inOrder(p->leftLink, visit, input1, input2); (*visit)(p->info, input1, input2); // 传递节点对象和两个外部整数 inOrder(p->rightLink, visit, input1, input2); } } template<class T> void BSTTemplate<T>::inOrderWithInputs(void (*visit)(T&, int&, int&), int input1, int input2) const { inOrder(root, visit, input1, input2); }
访问函数与调用示例
// 访问函数签名匹配函数指针要求 void MyFunction(MyObject& myObj, int& input1, int& input2) { // 使用input1、input2处理myObj,比如范围查找 if (myObj.getKey() >= input1 && myObj.getKey() <= input2) { cout << myObj << " "; } } // main函数中调用 int input1 = 10, input2 = 20; // 用户输入的整数 Tree.inOrderWithInputs(MyFunction, input1, input2);
方案二:使用Lambda表达式捕获外部变量(C++11及以上)
借助std::function接受任意可调用对象,用Lambda捕获外部参数,无需修改访问函数的签名:
先包含头文件
#include <functional>
调整遍历函数
template<class T> void BSTTemplate<T>::inOrder(Node<T>* p, const std::function<void(T&)>& visit) const { if (p != nullptr) { inOrder(p->leftLink, visit); visit(p->info); inOrder(p->rightLink, visit); } } template<class T> void BSTTemplate<T>::inOrderTraversal(const std::function<void(T&)>& visit) const { inOrder(root, visit); }
调用示例
int input1 = 10, input2 = 20; Tree.inOrderTraversal([input1, input2](MyObject& myObj) { // 直接在Lambda中使用捕获的input1和input2 if (myObj.getKey() >= input1 && myObj.getKey() <= input2) { cout << myObj << " "; } });
方案三:使用函数对象(仿函数,兼容C++98)
如果无法使用C++11特性,可以定义一个重载operator()的结构体,保存外部参数:
定义函数对象
struct MyVisitor { int input1; int input2; MyVisitor(int a, int b) : input1(a), input2(b) {} void operator()(MyObject& myObj) { // 使用成员变量input1、input2处理myObj if (myObj.getKey() >= input1 && myObj.getKey() <= input2) { cout << myObj << " "; } } };
调整遍历函数为模板(支持任意可调用对象)
template<class T, class Visitor> void BSTTemplate<T>::inOrder(Node<T>* p, Visitor visit) const { if (p != nullptr) { inOrder(p->leftLink, visit); visit(p->info); inOrder(p->rightLink, visit); } } template<class T, class Visitor> void BSTTemplate<T>::inOrderTraversal(Visitor visit) const { inOrder(root, visit); }
调用示例
int input1 = 10, input2 = 20; Tree.inOrderTraversal(MyVisitor(input1, input2));
内容的提问来源于stack exchange,提问作者Emil Lang
相关产品推荐
相关产品推荐

