提问人:Emil Lang 提问时间:8/5/2022 最后编辑:wohlstadEmil Lang 更新时间:8/5/2022 访问量:102
如果我编写一个函数指针以在 BST 模板中使用,他们可以接受 1 个以上的对象作为参数吗?
If I write a function pointer to use in BST template, can they take more than 1 object as argument?
问:
我为二叉搜索树写了一个模板。我希望重载按顺序遍历函数。当函数指针只接受类 T 的 1 个对象时,我可以让它工作。我希望它使用一个也使用 2 个整数值的函数指针,这样我就可以从 main 中的语句外部提取整数,然后我的函数指针将使用这些值在我的 BST 中查找对象。这可能吗?我将在下面展示我的代码。
例如,下面是一个仅使用对象的典型实现:T
template<class T>
void BSTTemplate<T>::inOrder(Node<T>* p) const
{
if (p != nullptr)
{
inOrder(p->leftLink);
cout << p->info << " ";
inOrder(p->rightLink);
}
}
template<class T>
void BSTTemplate<T>::inOrderTraversal() const
{
inOrder(root);
}
当我激活它时,我的程序会按顺序吐出 BST 中的所有节点。
下面是相同的代码,但带有函数指针:
template<class T>
void BSTTemplate<T>::inOrder(Node<T>* p, void (*visit) (T&)) const
{
if (p != nullptr)
{
inOrder(p->leftLink, *visit);
(*visit) (p->info);
inOrder(p->rightLink, *visit);
}
}
template<class T>
void BSTTemplate<T>::inOrderTraversal(void (*visit) (T&)) const
{
inOrder(root, *visit);
}
现在,在我的 I 中,我可以运行一个语句,例如:main()
//assume tree exists
Tree.inOrderTraversal(MyFunction);
其中 是一个 void 函数,使得MyFunction
void MyFunction(MyObject& myObj)
{
//does something
}
我的目标是我想在我的树中使用一个函数,以便它从“外部”接收 2 个整数。(基本上是用户输入)
我尝试过这样的事情:
//overloading inOrder
template<class T>
void BSTTemplate<T>::inOrder(Node<T>* p, void (*visit) (T&,int&,int&)) const
{
if (p != nullptr)
{
inOrder(p->leftLink, *visit);
(*visit) (p->info);
inOrder(p->rightLink, *visit);
}
}
template<class T>
void BSTTemplate<T>::inOrderWithInputs(void (*visit) (T&,int&,int&)) const
{
inOrder(root, *visit);
}
但是当我尝试像这样调用遍历函数时:main()
Tree.inOrderWithInputs(MyFunction(*arguments*));
解析器需要 类型为 、 an 和 another 的对象的参数。以前,当函数只有 void MyFunction(MyObject& myObj)
时,我只需要使用函数名称作为参数。由于自身有多个参数,我没有一个对象来填充它。T
int
int
MyFunction
理想情况下,我想做一些类似的事情
Tree.inOrderTraversal(MyFunction(input1,input2));
其中输入是从用户处获取的整数。然后,该函数操作这些值以创建键,然后使用该键按顺序搜索树。
请帮我把这些点连接起来?
答:
在 C++ 中,最好使用 std::function
而不是旧样式的函数指针。 是通过指定返回值和参数(根据需要任意数量)来实例化的模板。std::function
它支持传递您在代码中使用的全局函数以及 lambda(您也可以将类方法与 std::bind
一起使用)。
调用时,应将函数的参数作为附加参数提供(而不是使用实际调用函数并传递其返回值之类的参数)。inOrderTraversal
MyFunction(input1,input2)
查看完整示例:
#include <functional>
#include <iostream>
template <typename T>
class BSTTemplate
{
public:
//---------------------vvvvvvvvvvvvv----------------------------
void inOrderWithInputs(std::function<void(T&, int&, int&)> visit,
T& arg1, int& arg2, int& arg3) const // <--- the arguments for invoking the function
{
// Invoke the function with the arguments:
visit(arg1, arg2, arg3);
}
};
void GlobalFunc(float& arg1, int& arg2, int& arg3)
{
std::cout << "exceuting GlobalFunc with args: " << arg1 << ", " << arg2 << ", " << arg3 << std::endl;
}
int main()
{
BSTTemplate<float> bst;
float f{ 0 };
int i1{ 1 };
int i2{ 2 };
// Call with a global function:
bst.inOrderWithInputs(GlobalFunc,
f, i1, i2); // <--- the arguments for invoking the function
// Call with a lambda:
bst.inOrderWithInputs([](float& arg1, int& arg2, int& arg3)
{ std::cout << "exceuting lambda with args: " << arg1 << ", " << arg2 << ", " << arg3 << std::endl; },
f, i1, i2); // <--- the arguments for invoking the function
return 0;
}
输出:
exceuting GlobalFunc with args: 0, 1, 2
exceuting lambda with args: 0, 1, 2
评论
auto fn
评论
std::function
std::function