Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::async cannot be used with functions that receive a reference to an abstract class as a parameter?

I'm trying to execute a function that receives a parameter, which is a reference to an abstract class, through std::async but it seems that that is not valid for some reason. On the other hand, if I replace the mentioned reference by a pointer everything works.

Why does this happen? Is it generally better to pass abstract class parameters as pointers?

See the examples below:

Incorrect use of std::async

#include <iostream>
#include <future>

class AbsClass {
  public:
    virtual int f() = 0;
};

class ImplClass : public AbsClass {
  public:
    int f() override { return 21; }
};

int func(AbsClass &asbclass) {
  return 210 + asbclass.f();
}

int main() {
  ImplClass ic;
  AbsClass &ac = ic;

  // This causes a compilation failure:
  std::future<int> res = std::async(&func, ac);

  std::cout << res.get() << std::endl;
}

Failure displayed

/usr/include/c++/7/future:1745:5: error: invalid abstract parameter type ‘AbsClass’
main.cpp:4:7: note:   because the following virtual functions are pure within ‘AbsClass’:
 class AbsClass {
       ^~~~~~~~
main.cpp:6:17: note:    virtual int AbsClass::f()
     virtual int f() = 0;

Correct use of std::async

#include <iostream>
#include <future>

class AbsClass {
  public:
    virtual int f() = 0;
};

class ImplClass : public AbsClass {
  public:
    int f() override { return 21; }
};

int func(AbsClass *asbclass) {
  return 210 + asbclass->f();
}

int main() {
  ImplClass ic;
  AbsClass &ac = ic;

  std::future<int> res = std::async(&func, &ac);

  std::cout << res.get() << std::endl;
}
like image 671
Dan Avatar asked Oct 21 '25 12:10

Dan


1 Answers

The arguments needs to be stored, which means they are copied. And references can't be copied.

Therefore a reference wrapper was introduced, that can store references while also being able to be copied. You can use it with the helper function std::ref and std::cref:

std::future<int> res = std::async(&func, std::ref(ac));  // Pass ac by reference
like image 162
Some programmer dude Avatar answered Oct 23 '25 02:10

Some programmer dude



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!