Класс и std:: async на члене класса в С++

Я пытаюсь написать член класса, который несколько раз вызывает другой член класса.

Я написал простой пример проблемы и даже не могу ее скомпилировать. Что я делаю неправильно с вызовом std:: async? Я думаю, проблема связана с тем, как я передаю функцию.

#include <vector>
#include <future>
using namespace std;
class A
{

int a,b;
public: 
A(int i=1, int j=2){ a=i; b=j;} 

std::pair<int,int> do_rand_stf(int x,int y)
{
    std::pair<int,int> ret(x+a,y+b);
    return ret;
}

void run()
{
    std::vector<std::future<std::pair<int,int>>> ran;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            auto hand=async(launch::async,do_rand_stf,i,j);
            ran.push_back(hand);    
        }
    }
    for(int i=0;i<ran.size();i++)
    {
        pair<int,int> ttt=ran[i].get();
        cout << ttt.first << ttt.second << endl;
    } 
}
};
int main()
{
A a;
a.run();
}

компиляции:

g++ -std=c++11 -pthread main.cpp 

Ответ 1

do_rand_stf является нестатической функцией-членом и поэтому не может быть вызвана без экземпляра класса (неявный параметр this). К счастью, std::async обрабатывает его параметры, такие как std::bind, и bind в свою очередь может использовать std::mem_fn, чтобы превратить указатель на функцию-член в функтор, который принимает явный параметр this, поэтому все, что вам нужно сделать, это передать this на вызов std::async и использовать синтаксис указателя синтаксической функции-члена при передаче do_rand_stf:

auto hand=async(launch::async,&A::do_rand_stf,this,i,j);
Тем не менее, существуют другие проблемы в коде. Во-первых, вы используете std::cout и std::endl без #include ing <iostream>. Более серьезно, std::future не является скопируемым, только подвижным, поэтому вы не можете push_back именованный объект hand без использования std::move. Или просто передайте результат async в push_back напрямую:
ran.push_back(async(launch::async,&A::do_rand_stf,this,i,j));

Ответ 2

Вы можете передать указатель this в новый поток:

async([this]()
{
    Function(this);
});