omegasbk omegasbk - 2 months ago 20
C++ Question

Adding binary tree member using async fails to compile

I implemented some basic functionality for adding data to binary tree. I wanted to practice async calls and therefore I decided to implement Node adding as async task. However, I get build errors on the line that calls async task. Here is the sample code:

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


The error I get:

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


What am I doing wrong?

Answer

On which Node do you want to call AddNodeAsync? *this? or root? That's exactly the problem: you don't have an instance to call AddNodeAsync on!

You want to specify which instance as first parameter of AddNodeAsync (it's implicit):

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

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