2

I have a class called MatrixAlt and i'm trying to multi thread a function to do some work on that matrix.

My general method worked when I just implemented it in a couple of functions. But when I try to bring it into the class methods, I get an error.

The problematic line (or where it highlights anyway) is 4 lines from the end and the error message is in the comments just above it.

#include <vector>
#include <future>
#include <thread>

class MatrixAlt
{
    public:
    MatrixAlt();

    // initilaise the matrix to constant value for each entry
    void function01(size_t maxThreads);
    void function02(size_t threadIndex);

};

MatrixAlt::MatrixAlt()
{

}

void MatrixAlt::function02(size_t threadIndex)
{
    // do some stuff 
    return;

}


void MatrixAlt::function01(size_t maxThreads)
{

    // To control async threads and their results
    std::vector<std::future<bool>> threadsIssued;

    // now loop through all the threads and orchestrate the work to be done
    for (size_t threadIndex = 0; threadIndex < maxThreads; ++threadIndex)
    {
        // line 42 gives error:
        // 'MatrixAlt::function02': non-standard syntax; use '&' to create a pointer to member
        // 'std::async': no matching overloaded function found
        threadsIssued.push_back(std::async(function02, threadIndex));
    }
    return;
}
5
  • 2
    Use &MatrixAlt::function02 as the error message suggests. Commented Oct 26, 2017 at 17:26
  • 1
    Class methods may be implemented as functions under the hood, but in C++, a method pointer is distinct from a function pointer, and they have their own rules for how to work with them. Commented Oct 26, 2017 at 17:28
  • Possible duplicate of stackoverflow.com/questions/13669094/… Commented Oct 26, 2017 at 17:38
  • I looked at the possible duplicate question and confess that I'm not smart enough to see the analogy. I'm pretty new to c++ but have been coding for 40 years off and on. It means some concepts that are obvious to many remain a bit mysterious to me. Sorry! Commented Oct 26, 2017 at 17:51
  • please dont fix the errors in your question according to answers/comments when it is about the problem you are asking for. I rolled back to the original version because as it was, the error message was completely unrelated to the code and the question didnt make much sense Commented Oct 26, 2017 at 17:58

2 Answers 2

1

Your first problem is solved like this

threadsIssued.push_back(std::async(&MatrixAlt::function02, this, threadIndex));

You need to specify the exact class::function and take its address and which instance of the class your doing it for, and then the parameters.

The second problem which you haven't see yet is this line

 std::vector<std::future<bool>> threadsIssued;

All those futures will be lost in scope exit, like tears in rain. Time to destroy.

Freely after Blade runner.

All those moments will be lost in time, like tears in rain. Time to die.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm still feeling my way and I tried using the solution to my first problem and it won't compile. The error is as follows: no instance of overloaded function "std::async" matches the argument list argument types are : (bool (MatrixAlt::*)(size_t threadIndex), MatrixAlt *, size_t) It's not obvious to me what I should do to fix that. The second problem can sit and wait for me a while yet
re my second problem: Are you saying that because I don't do anything with the threads then the processes will die when it hits the return? If yes, it may be relevant that I'd stripped out this (not yet working) code as I was trying to create the minimal code to post that illustrated the problem I was experiencing, float accumulator = 0; for (int index = 0; index < threadsToUse; ++index) { double temp = futureVector[index].get(); accumulator += temp; } If it's nothing to do with that, any chance you could elaborate slightly? Thanks
When you exit the function all the futures in the vectors are lost, but the code you describe there should use them before exit.
0

Whenever you have a member function in C++, that function takes the object itself as an implicit first argument. So you need to pass the object as well, but even then, it can't be called with the same syntax as a normal function that takes the object.

The simplest way to setup an asynchronous job in C++ is typically just to use lambdas. They've very clear and explicit. So, for example, you could change your call to:

threadsIssued.push_back(std::async([this] (size_t t) { this->function02(t);}, threadIndex));

This lambda is explicitly capturing the this pointer, which tells us that all of the function02 calls will be called on the same object that the calling function01 is called on.

In addition to being correct, and explicit, this also helps highlight an important point: all of the function02 objects will be running with mutable access to the same MatrixAlt object. This is very dangerous, so you need to make sure that function02 is thread safe, one way or another (usually easy if its conceptually const, otherwise perhaps need a mutex, or something else).

2 Comments

I'm feeling my way. The suggested line would only compile if I change this line: std::vector<std::future<bool>> threadsIssued; to std::vector<std::future<void>> threadsIssued; I'll need to work out the implications of that tomorrow Thanks for the threadsafe warning. At the moment, I believe that will be ok as I'm carving up the matrix and operating on discrete chunks of it in the actual code.
@PBS Yes because function02 returns void, so where can it get the bool from? Sorry I missed that point in my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.