编写一个通用遍历函数,允许灵活地处理具有不同参数的多个函数
Writing a generic traverse function that allows the flexibility of dealing with multiple functions with differing parameters
我想使用 std::function 来帮助我运行一个遍历 BST 并调用参数化函数的通用遍历函数。
我的困难在于参数化函数在其自身的参数中变化。
因此,例如,我要概括以下三个函数(它们的参数都不同(。
//populates an array with the values in the BST by traversing the BST
void LinkedBST<T>::populate(T const * const data, size_t & I, Node *x)
{
data[i++] = x->val;
}
//insert unique values of another BST into "this" BST: traverses the other BST and inserts every value
void LinkedBST<T>::insert(Node *x)
{
insert(x->val);
}
与其为上述每个函数编写单独的遍历函数,我希望能够将它们传递到一个通用遍历函数中,如下所示:
void LinkedBST<T>::traverse(Node *x, auto func)
{
if(x == nullptr)
return;
traverse(x->left, func);
func( <parameters> );
traverse(x->right, func);
}
有什么办法可以做到这一点吗?如果有,你能帮我做吗?
谢谢:)
通常,您需要找到一种方法来标准化所有遍历回调的签名。一种选择是使用 lambda 并利用 lambda 捕获来减少函数的参数数量。
void LinkedBST<T>::populate(T const * const data, size_t & I)
{
traverse(root, [&](Node * x) {
data[i++] = x->val;
});
}
请注意,同一遍历函数不能用于compare
因为您需要同时遍历两棵树。目前还不清楚insert
应该做什么,但从评论中听起来也需要同时遍历。
一种解决方案是模板化遍历函数以采用函数对象。 然后,不要在 traverse
函数中指定参数,而是将这些参数移动到函数对象,并让函数对象的operator()
在调用时处理详细信息:
template <typename func>
void LinkedBST<T>::traverse(Node *x, func fn)
{
if(x == nullptr)
return;
traverse(x->left, fn);
fn(x->val);
traverse(x->right, fn);
}
struct some_func
{
int param1;
int param2;
int param3;
some_func(int p1, int p2, int p3) : param1(p1), param2(p2), param3(p3) {}
void operator()(int node_value)
{
std::cout << "The node value is " << node_value << "n";
// the parameters are param1, param2, param3
}
};
调用 operator()
(调用函数(时,您现在拥有节点值以及您在对象内设置的所有参数。
然后可以做这样的事情:
Node *node_ptr;
//...
LinkedBST<int> the_list;
//...
some_func f(1,2,3); // we want to use 1,2,3 as the parameters to the custom function
the_list.traverse(node_ptr, f);
下面是使用虚拟类显示基础知识的简化版本。
您也可以通过以下技术使用 lambda:
Node *node_ptr;
//...
LinkedBST<int> the_list;
//...
int arg1=1, arg2=2, arg3=3;
the_list.traverse(node_ptr,
[&](int node_value){std::cout << "The node value is " <<
node_value << "n" << arg1 << " " <<
arg2 << " " << arg3;});
相关文章:
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- std::string 构造函数如何处理固定大小的 char[]?
- 模板函数如何处理可能共享一个交集的多个类型名称?
- 如何编写具有相同名称的相同函数,该函数在C++中几乎以相似的方式处理不同的类参数?
- 为什么这个噪声函数不处理否定参数?
- 传递多处理.将对象值为 ctype 函数?
- 处理简单 cpp 类构造函数中的错误
- 使用返回对象的函数处理错误
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在双重继承的情况下如何处理非标准构造函数
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 在线程函数中处理数据向量时进行线程竞速
- 某些 boost::asio 异步函数是否将处理程序连接到操作,以便处理程序被触发一次?
- 如何处理冲突的函数和变量名称?
- 如何在复杂的算法中处理goto函数?
- 如何让 atoi() 函数处理字符串
- 生产编译器如何在流控制上实现析构函数处理
- 使用 lambda 函数处理 C++ libsigc++ 信号
- 为数组创建c++ max函数:处理数组大小为0的情况的正确方法是什么?