std::thread::_Invoker error while programming withthreads

Viewed 1194

EDIT: I'm trying to learn how to use threads in c++. I've a problem with my code, it gives me the following error:

no matching function for call to 'std::thread::_Invoker<std::tuple<void (matrix_product<int, 0, 0>::*)(matrix_wrap<int>&, int, const matrix_wrap<int>&, const matrix_wrap<int>&), matrix_wrap<int>, int, matrix_wrap<int>, matrix_wrap<int> > >::_M_invoke(std::thread::_Invoker<std::tuple<void (matrix_product<int, 0, 0>::*)(matrix_wrap<int>&, int, const matrix_wrap<int>&, const matrix_wrap<int>&), matrix_wrap<int>, int, matrix_wrap<int>, matrix_wrap<int> > >::_Indices)'
  operator()()

This is the piece of code that gives me the error (it was working before I wrote this):

void do_multiply_fico(matrix_wrap<T> result, matrix_wrap<T> lhs, matrix_wrap<T> rhs) {
        // Create an array of threads
        std::thread threads[lhs.get_height()];
        for (int i = 0; i < lhs.get_height(); ++i) {
            // Initialize each thread with the function responsible of multiplying only a part of the matrices
            threads[i] = std::thread(multiply_threading, result, i, lhs, rhs);
        }
        for (int i = 0; i < lhs.get_height(); ++i) {
            // Wait until each thead has finished
            threads[i].join();
        }
    }

    void multiply_threading(matrix_wrap<T>& result, const int thread_number, const matrix_wrap<T>& lhs, const matrix_wrap<T>& rhs){
        const unsigned height = result.get_height();
        const unsigned width = result.get_width();
        const unsigned span = lhs.get_width();
        assert(span==rhs.get_height());
        for (unsigned i=0; i!=height; ++i) {
            for (unsigned j = 0; j != width; ++j) {
                for (unsigned k = 0; k != span; ++k) {
                    result(i, j) += lhs(i, k) * rhs(k, j);
                }
            }
        }

    }

thanks in advance for the help.

1 Answers

It looks like you're trying to construct std::thread from a member function. That's not going to work: you need an instance to invoke it.

You also have a more serious problem, in that reference arguments will, by default, be passed to the thread constructor as value types. You'd need to wrap them in std::ref to get it to compile and exhibit the expected behavior.

The easier way around all that, though, would just be to pass a lambda to std::thread:

threads[i] = std::thread([this, &result, i, &lhs, &rhs](){
   multiply_threading(result, i, lhs, rhs);
});

That way the wrapping of arguments is done through lambda capture, rather than through the vagaries of std::thread. (Reference capture can under certain circumstances be unsafe, but since you're joining everything in the same function you don't need to worry about that.) Note that i is captured by value, since you're going to change its value in later iterations and need the threads you already created to capture the value it had when you created them.

Related