C++ 函数作为具有默认值的参数
我想为二叉树创建一个类:C++ 函数作为具有默认值的参数,c++,function-pointers,C++,Function Pointers,我想为二叉树创建一个类: struct TreeNode { explicit TreeNode(int _value) : value(_value) {} int value = 0; TreeNode* left = nullptr; TreeNode* right = nullptr; }; class BTree { public: void Add(int value); void PrintPostOrde
struct TreeNode {
explicit TreeNode(int _value) : value(_value) {}
int value = 0;
TreeNode* left = nullptr;
TreeNode* right = nullptr;
};
class BTree {
public:
void Add(int value);
void PrintPostOrder(void (*func)() = print_current);
~BTree();
private:
TreeNode* root = nullptr;
void print_current();
void delete_node();
};
BTree::~BTree() {
PrintPostOrder(delete_node);
}
我的想法-对于析构函数和打印,我需要进行二叉树遍历。因此,我想创建函数遍历,并将函数
用作其中的参数:
如果需要打印func=print
,对于析构函数func=delete\u节点
此处有错误:
void PrintPostOrder(void (*func)() = print_current);
类型为“void(BTree::)()”的默认参数不兼容
使用类型为“void()()”的参数
当参数是一个函数时,我不知道如何设置参数的默认值。原则上,您可以像以前那样为函数设置默认参数。问题是成员函数与自由函数的类型不同 这是一个自由函数指针
void(*func)(
),而print\u current
是类型为void(BTree::)()
的成员函数
修复参数类型或使用自由函数作为默认参数
另外,不要忘记成员函数与自由函数有着本质的区别,因为您需要一个实例来调用它们。原则上,您可以像以前那样为函数设置默认参数。问题是成员函数与自由函数的类型不同 这是一个自由函数指针
void(*func)(
),而print\u current
是类型为void(BTree::)()
的成员函数
修复参数类型或使用自由函数作为默认参数
另外,不要忘记成员函数与自由函数有本质的区别,因为您需要一个实例来调用它们。
print\u current
和delete\u node
都是成员函数,因此您需要一个成员函数指针:
class BTree {
public:
void PostOrder(void (BTree::*fn)() = &BTree::print_current) {
std::invoke(fn, this);
}
~BTree() {
PostOrder(&BTree::delete_node);
}
private:
void print_current();
void delete_node();
};
为了获得更大的灵活性,您可以将PostOrder
作为模板:
struct TreeNode {};
class BTree {
public:
template<class Fn>
void PostOrder(Fn fn) {
std::invoke(fn);
}
void PostOrder() {
PostOrder([this] { print_current(); });
}
~BTree() {
TreeNode* node;
PostOrder([this, node] { delete_node(node); });
}
private:
void print_current();
void delete_node(TreeNode*);
};
struct TreeNode{};
B类树{
公众:
模板
无效后序(Fn-Fn){
调用(fn);
}
作废邮购(){
后序([this]{print_current();});
}
~b树(){
TreeNode*节点;
后序([this,node]{delete_node(node);});
}
私人:
无效打印_当前();
void delete_节点(TreeNode*);
};
print\u current
和delete\u node
是成员函数,因此需要成员函数指针:
class BTree {
public:
void PostOrder(void (BTree::*fn)() = &BTree::print_current) {
std::invoke(fn, this);
}
~BTree() {
PostOrder(&BTree::delete_node);
}
private:
void print_current();
void delete_node();
};
为了获得更大的灵活性,您可以将PostOrder
作为模板:
struct TreeNode {};
class BTree {
public:
template<class Fn>
void PostOrder(Fn fn) {
std::invoke(fn);
}
void PostOrder() {
PostOrder([this] { print_current(); });
}
~BTree() {
TreeNode* node;
PostOrder([this, node] { delete_node(node); });
}
private:
void print_current();
void delete_node(TreeNode*);
};
struct TreeNode{};
B类树{
公众:
模板
无效后序(Fn-Fn){
调用(fn);
}
作废邮购(){
后序([this]{print_current();});
}
~b树(){
TreeNode*节点;
后序([this,node]{delete_node(node);});
}
私人:
无效打印_当前();
void delete_节点(TreeNode*);
};
太棒了!我得到了它。我可以再问一个问题吗:如果delete\u node
函数有一个参数(指向要删除的节点的指针),但print\u current
没有,该怎么办。我如何将函数作为参数提取,而它可能有参数,也可能没有参数?@Mikhail_Sam,最简单的解决方案是将其作为模板。@Evg看起来是另一个大问题。谢谢大家!@Mikhail_Sam在这种情况下,我会将两者包装在一个不带参数的lambda中。当然,这取决于您在什么时候知道要传递的参数。也许最好打开另一个问题(以防你在别处找不到答案)太棒了!我得到了它。我可以再问一个问题吗:如果delete\u node
函数有一个参数(指向要删除的节点的指针),但print\u current
没有,该怎么办。我如何将函数作为参数提取,而它可能有参数,也可能没有参数?@Mikhail_Sam,最简单的解决方案是将其作为模板。@Evg看起来是另一个大问题。谢谢大家!@Mikhail_Sam在这种情况下,我会将两者包装在一个不带参数的lambda中。当然,这取决于您在什么时候知道要传递的参数。也许最好打开另一个问题(以防你在别处找不到答案)请不要垃圾邮件标签,你的代码是关于一棵树的,但问题与此无关。我更改了标签,如果您不满意,请重新更改(fwiw,我没有添加成员函数指针
标签,因为当标签已经有一半答案时,我总是觉得很奇怪)请不要垃圾标签,您的代码是关于树的,但问题与此无关。我更改了标记,如果您不满意,请将其更改回来(fwiw,我没有添加成员函数指针
标记,因为当标记已经有一半答案时,我总是觉得很奇怪)我可以使用void(BTree::*func)(=print\u current
还是需要使用void(BTree::*func)(=&print\u current)
?或者void(BTree::*func)(=&BTree::print_current)
?@Mikhail_Sam,不幸的是,它应该是如此冗长,&BTree:>print_current
。我认为printpostore
应该被命名为posterorder
。我可以使用void(BTree:*func)(=print_current
,或者我需要使用void(BTree:*func)()=&print_current)
?或者void(BTree::*func)(=&BTree::print_current)
?@Mikhail_Sam,不幸的是,它应该是如此冗长,&BTree::print_current
。我认为printpostore
应该被命名为postore
。