2016-09-18 56 views
0

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

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  

我在做什么错?

+2

取而代之的是'bind'呼叫和呼叫'AddNodeAsync'的,它可以全部使用单个[lambda表达式](http://en.cppreference.com/w/cpp/language/lambda)完成。 –

+0

用以下语句替换这两个语句: auto ftr = async(launch :: async,[&](){AddNodeAsync(root,* this);}); 做到了!但为什么第一个版本不起作用? – omegasbk

回答

1

您想拨打哪个NodeAddNodeAsync*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

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

你忘了参数:

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