作为具有默认值的参数的函数

Function as argument with default value

我想为二叉树创建class:

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);
}

我的想法 - 对于析构函数和打印,我需要进行二叉树遍历。所以我想创建函数 Traversal 并在其中使用 function 作为参数: 如果我需要打印 func = print 和析构函数 func = delete_node.

错误在这里:

void PrintPostOrder(void (*func)() = print_current);

the default argument of type "void (BTree :: ) ()" is incompatible with the parameter of type "void () ()"

当参数是函数时,我不知道如何设置参数的默认值。

原则上,您可以按照您的方式为函数设置默认参数。问题是成员函数与自由函数的类型不同。

这是一个自由函数指针void (*func)(),而print_currentvoid (BTree :: ) ()类型的成员函数。

要么修复参数类型,要么使用自由函数作为默认参数。

另外不要忘记成员函数与自由函数有根本的不同,因为你需要一个实例来调用它们。

print_currentdelete_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*);
};