用于就地修改的过载功能参数是否

时间:2018-01-20 23:10:23

标签: c++ function reference overloading

我正在使用二元搜索树,订单很重要。

如果节点/节点被修改,则树需要更新以保持顺序正确。

我想要做的是重载访问方法,例如preOrderTraversal;这样就可以区分该函数是否会修改节点。

void preOrderTraversal(std::function<void(Type)> visit); // read only visit

void preOrderTraversal(std::function<void(Type &)> visit); // write visit, update needed afterwards

如果传入的std::function是值参数类型,则表示只读访问,因此无需更新树;如果std::function是引用类型,则将修改树,因此需要调用update方法。

我知道我可以将preOrderTraversal方法标记为const和非const重载。但是,如果我们知道函数传入是否可以更改树节点并重载它们,那么会很清楚吗?

template<typename Type>
class BinaryTree {
public:
    struct Node {
        Type data;
        Node* left{ nullptr };
        Node* right{ nullptr };
        Node(Type && value) : data{ std::move(value) } { }
        Node() = delete;
    };
    // ... omit unrealated parts ...

    // head, left leaf, right leaf
    // value type, tree will not be modified
    void preOrderTraversal(std::function<void(Type)> visit) {
        std::cout << "void preOrderTraversal(std::function<void(Type)>)" << std::endl;
        preorder_utility(visit);
    }
    // reference type, tree will be modified; so the tree need update order of nodes.
    void preOrderTraversal(std::function<void(Type&)> visit) {
        std::cout << "void preOrderTraversal(std::function<void(Type&)>)" << std::endl;
        preorder_utility(visit);
        update(); // update function to keep the tree in binary search tree order.
    }
private:
    template <typename Function>
    void preorder_utility(Function visit) {
        if( nullptr == root ) return;
        std::stack<Node*> stack;
        stack.push(root);
        while( !stack.empty() ) {
            auto node = stack.top();
            stack.pop();
            visit(node->data);
            if( node->right ) {
                stack.push(node->right);
            }
            if( node->left ) {
                stack.push(node->left);
            }
        }
    }
    Node* root{nullptr};
};

这样我们就可以有访问函数可以修改树了。

// just as an example, readonly can not change the tree,
// while write may change the tree
void readonly(double value) {
    // value inside tree will not change
    value += 10.0;
    std::cout << value << std::endl;
}

void write(double & value) {
    // value inside tree will change
    value += 10.0;
    std::cout << value << std::endl;
}

所以

int main() {
    BinaryTree<double> btree;

    // ... working on the tree..., push, pop, etc.

    btree.preOrderTraversal(readonly);
    btree.preOrderTraversal(write);
}

[更新] 看起来如果我使readonly采用rvalue-reference,代码将编译并运行。

 // this will call void preOrderTraversal(std::function<void(Type)> visit)
 // hence no update method will be called.
void readonly(double && value) {
    // value inside tree will not change
    value += 10.0;
    std::cout << value << std::endl;
}

0 个答案:

没有答案