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

时间:2016-09-18 10:21:50

标签: c++ asynchronous

我实现了一些将数据添加到二叉树的基本功能。我想练习异步调用,因此我决定将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.0\vc\include\type_traits  1468    

我做错了什么?

3 个答案:

答案 0 :(得分:1)

查看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);

答案 1 :(得分:1)

您忘记了参数:

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

答案 2 :(得分:1)

您想要Node致电AddNodeAsync*this?还是root?这正是问题所在:你没有一个实例来调用AddNodeAsync

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

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

此外,it is better to use lambdas instead of std::bind