Mikhail_Sam
Mikhail_Sam

Reputation: 11238

Function as argument with default value

I want to create class for binary trees:

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

My idea - for destructor and for Printing I need to do binary tree traversal. So I want to create function Traversal and use function as parameter in it: if I need to print func = print and for destructor func = delete_node.

Error is here:

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

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

I don't know how to set default value for parameter when parameter is a function.

Upvotes: 1

Views: 63

Answers (2)

Evg
Evg

Reputation: 26362

print_current and delete_node are member functions, so you need a member function pointer:

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

For more flexibility you can make PostOrder a template:

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

Upvotes: 3

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123431

In principle you set a default parameter for a function the way you did. The problem is that a member function is of different type than a free function.

This is a free function pointer void (*func)(), while print_current is a member function of type void (BTree :: ) ().

Either fix the parameter type or use a free function as default parameter.

Also do not forget that member functions are fundamentally different from free functions, because you need an instance to call them.

Upvotes: 3

Related Questions