1

I'm failing to understand what I've done wrong. I've gone through several examples as well as the cppreference and come up with nothing.

When I try to execute a number of threads using a for loop, I call a function "evaluate". When I run the program in series there is no compiling problem, however adding multithreading yields the following:

GraphEvaluate.cpp:35:70: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, const std::vector<std::vector<double> >&, const std::vector<InVec>&, InVec&, Graph&)’
   t[iii] = std::thread(evaluate, controlSpace, stateSpace, box, graph);

I don't understand how "evaluate" is an 'unresolved overloaded function type'.

Here is the code:

...
std::thread t[g_threads-1];


int counter(0);


for(int iii = 0 ; iii < (g_threads - 1) ; ++iii)
{
    InVec box(stateSpace.at(counter));
    t[iii] = std::thread(evaluate, controlSpace, stateSpace, box, graph);
    counter += 1;
}


for(int iii = 0 ; iii < (g_threads - 1) ; ++iii)
{
    t[iii].join();
}
...

And the evaluate function:

void evaluate(const std::vector<std::vector<double>> &controlSpace, 
    const std::vector<InVec> &stateSpace, InVec box, Graph &graph)
{
    std::vector<InVec> boxList;  // create empty vector of InVec objects
    SPnode ASP(box);             // create subpaving node with box
    mince(ASP, g_epsilon);       // mince box
    treeToList(ASP, boxList);    // convert tree to list for efficient mapping


    // map each box in boxList with mapping defined in GraphMapping.cpp for each
    // controller value
    for (auto control : controlSpace)
    {
        ImList imageList;

        for (auto box : boxList)
        {
            imageList.addBox(mapping(box, control));
        }

        InVec intersectionBox(inclusionMap(imageList));
        std::vector<InVec> intersectingBoxes;  // list of boxes in state space
        // that intersect with intersectionBox

        for (auto ssBox : stateSpace)
        {
            if (!(noIntersection(ssBox, intersectionBox))) 
                intersectingBoxes.push_back(ssBox);
        }


        std::vector<int> nodeList; // list of nodes that box (function input)
        // points to with the given control

        if (!(intersectingBoxes.empty()))
        {
            for (auto ssBox : intersectingBoxes)
            {
                for (auto image : imageList.getList())
                {
                    if (!(noIntersection(ssBox, image)))
                    {
                        nodeList.push_back(ssBox.getBoxNumber());
                        break;
                    }
                }
            }
        }


        if (!(nodeList.empty()))
        {
            for (auto node : nodeList)
            {
                graph.setAdjList(box.getBoxNumber(), Edge(node, control));
            }
        }
    }
}

Any help is appreciated.

duncster94
  • 570
  • 6
  • 23
  • 2
    You need use `std::ref`, ie `std::thread(evaluate, std::ref(controlSpace), std::ref(stateSpace), box, std::ref(graph));` – chema989 Jun 23 '16 at 20:08

1 Answers1

2

The constructor of std::thread deduces its argument types and stores them by value.

C++ template function argument type deduction mechanism deduces type T from an argument of type T&. Hence, all arguments to std::thread are passed by value. @MaximEgorushkin

If you need to call a function that its arguments are references from a std::thread, wrap the argument using std::ref(). For example:

std::thread(evaluate, std::ref(controlSpace), std::ref(stateSpace), box, std::ref(graph));

On the other hand, you need to change the declaration of evaluate function like:

void evaluate(std::vector<std::vector<double>> controlSpace, 
    std::vector<InVec> stateSpace, InVec box, Graph graph);

For more information, see this post.

chema989
  • 3,962
  • 2
  • 20
  • 33
  • Oddly enough, this doesn't seem to be working, I get the same error message as above, just with std::reference_wrapper in front of the wrapped parameters – duncster94 Jun 23 '16 at 20:28
  • 1
    is `evaluate` a member class? – chema989 Jun 23 '16 at 20:32
  • Turns out `evaluate` was a function I had used in another code but had included as a friend to a few of my objects. I still find it odd that `std::thread` would find this friend declaration when none of my other functions do. Any idea? – duncster94 Jun 23 '16 at 20:49