使用async添加二叉树成员无法编译

Adding binary tree member using async fails to compile

本文关键字:编译 成员 二叉树 async 添加 使用      更新时间:2023-10-16

我实现了一些向二叉树添加数据的基本功能。我想练习异步调用,因此我决定将Node添加实现为异步任务。但是,我在调用异步任务的行上得到构建错误。下面是示例代码:

struct Node
{
    static Node *root;
    static mutex _mtx;
    int _value;
    Node *_left;
    Node *_right;
    Node()
    {
        _left = nullptr;
        _right = nullptr;
    }
    Node(int value)
    {       
        _left = nullptr;
        _right = nullptr;
        _value = value;
        if (!root) root = this;
        else
        {
            lock_guard<mutex> lck(_mtx);
            auto func = bind(&Node::AddNodeAsync, root, ref(*this));
            auto ftr = async(launch::async, func); // Error!!!!!!       
        }
    }
    void AddNodeAsync(Node *parentNode, Node &nodeToAdd)
    {
        lock_guard<mutex> lck(_mtx);
        AddNode(parentNode, nodeToAdd);
    }
    void AddNode(Node *parentNode, Node &nodeToAdd)
    {           
        if (nodeToAdd._value < parentNode->_value)
        {
            if (parentNode->_left == nullptr)
            {
                parentNode->_left = &nodeToAdd;
            }
            else
            {
                AddNode(parentNode->_left, nodeToAdd);
            }
        }
        else if (nodeToAdd._value > parentNode->_value)
        {
            if (parentNode->_right == nullptr)
            {
                parentNode->_right = &nodeToAdd;
            }
            else
            {
                AddNode(parentNode->_right, nodeToAdd);
            }
        }
        else
        {
            assert(false);
        }
    }
};

我得到的错误:

Severity    Code    Description Project File    Line    Suppression State
Error   C2893   Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'    BinaryTree  c:program files (x86)microsoft visual studio 14.0vcincludetype_traits  1468    

我做错了什么?

您想在哪个Node上调用AddNodeAsync ?*this吗?还是root ?这正是问题所在:您没有一个实例来调用AddNodeAsync !

你想指定哪个实例作为AddNodeAsync的第一个参数(它是隐式的):

auto func = bind(&Node::AddNodeAsync, this, root, *this);
                                      ^^^^
                                   instance to call AddNodeAsync on

另外,最好使用lambdas而不是std::bind

看看void AddNodeAsync(Node *parentNode, Node &nodeToAdd),它有两个参数,它也是一个成员函数,它应该得到this绑定。现在看看你的bind:

auto func = bind(&Node::AddNodeAsync, root, ref(*this));

所以,bind接受第一个和第二个参数(第一个是成员函数,第二个是要绑定的this),并将它们绑定在一起,这取决于你在哪里写

root->AddNodeAsync(ref(*this));
如您所见,

缺少一个参数。例如,这个程序编译得很好:

auto func = bind(&Node::AddNodeAsync, root, root, *this);

您忘记了这个参数:

auto func = bind(&Node::AddNodeAsync,this, root, ref(*this));
auto ftr = async(launch::async, func);

无论如何,您可以在一行中使用lambda表达式:

auto ftr = async(launch::async, [this]{ this->AddNodeAsync(root,*this); });