c++multithreadingstdasync

How do I pass a function from another class while calling std::async from a function of different class?


I have two classes, CameraToBEV and BEVTest. The CameraToBEV contains the function process().

class CameraToBEV : 
{
    public:
        CameraToBEV(std::vector<Point2f>, cv::Point2f, cv::Point2f);
        /*
            process(json Object, ROI Bounding box, Output Dimensions, Input Dimensions)
        */
        cv::Mat process(json&, std::vector<Point2f> = { Point2f(765,57), Point2f(1860,57), Point2f(27, 1000) ,Point2f(1800, 1000) }, Point2f=Point2f(1920,1080), Point2f=Point2f(1920, 1080));
};

And the class BEVTest contains the function runtests() which calls the function process() in a for loop.

void BEVTest::runTests()
{   
    CameraToBEV cbevObj(RoiBbox, OutputDim, InputDim);

    std::vector<std::future<cv::Mat>> processingThread;
    
        for (int i = 0; i < jsonObjects.size(); i++) {

            processingThread.emplace_back(std::async(std::launch::async, &CameraToBEV::process,this, jsonObjects[i]));
            
                
        }
    
}
 

I am trying to do multithreading using std::async of the for loop so that the process function gets executed parallelly for each JSON object.

But when I build this code I am getting the following error;

Error   C2672   'std::async': no matching overloaded function found 
 
Error   C2893   Failed to specialize function template 'std::future<_Select_invoke_traits<decay<_Ty>::type,decay<_ArgTypes>::type...>::type> std::async(std::launch,_Fty &&,_ArgTypes &&...)' 

So I tried another way of calling std::async

processingThread.emplace_back(std::async(std::launch::async, &cbevObj.process,this, jsonObjects[i]));

and

processingThread.emplace_back(std::async(std::launch::async, &cbevObj.process,jsonObjects[i]));

and

processingThread.emplace_back(std::async(std::launch::async, &cbevObj.process,jsonObjects[i], ROIBbox, OutputDim, InputDim));

Still, I am getting errors.

Note:

I am able to call std::async without any error or problem if I call the function of the same class from another function of the same class which has a for loop, as mentioned in this answer. It's only when I am calling a function of a different class from another class that has for loop that I am facing errors.

EDIT: After trying the comments

processingThread.emplace_back(std::async(std::launch::async, &CameraToBEV::process,&cbevObj, jsonObjects[i], RoiBbox, OutputDim, InputDim));

and alternately without passing default values to process()

processingThread.emplace_back(std::async(std::launch::async, &CameraToBEV::process,&cbevObj, jsonObjects[i]));

The error is:

Error   C2672   'std::async': no matching overloaded function found 

Error   C2893   Failed to specialize function template 'std::future<_Select_invoke_traits<decay<_Ty>::type,decay<_ArgTypes>::type...>::type> std::async(std::launch,_Fty &&,_ArgTypes &&...)'   

Error   C2672 std::vector<std::future<cv::Mat>,std::allocator<std::future<cv::Mat>>>::emplace_back': no matching overloaded function found  

Decleration of jsonObjects in BEVTests:

class BEVTest
{
    Point2f InputDim, OutputDim;
    std::vector<Point2f> RoiBbox;
    std::string outputPath, inputJsonPath;
    std::vector<json> jsonObjects;

public:  
    BEVTest(std::string, std::string, std::vector<cv::Point2f>, cv::Point2f, cv::Point2f);
    void loadData(); 
    void runTests();
    json parseJson(std::string);
};

Solution

  • As per the comment if the member function you want to run using std::async is CameraToBEV::process then the parameter passed immediately after &CameraToBEV::process should be a pointer to a valid CameraToBEV instance.

    In addition, std::async will, by default, pass parameters by value. However the function you're calling has the signature...

    cv::Mat process(json&, std::vector<Point2f> = { Point2f(765,57), Point2f(1860,57), Point2f(27, 1000) ,Point2f(1800, 1000) }, Point2f=Point2f(1920,1080), Point2f=Point2f(1920, 1080));
    

    so it expects the first parameter as a non-const reference to a json object. The call to std::async should therefore be (untested)...

    processingThread.emplace_back(std::async(std::launch::async, &CameraToBEV::process, &cbevObj, std::ref(jsonObjects[i])));
    

    (Note the use of std::ref)