Почему std :: async нельзя использовать с функциями, которые получают ссылку на абстрактный класс в качестве параметра? - PullRequest
1 голос
/ 07 июля 2019

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

Почему это происходит?Как правило, лучше передавать параметры абстрактного класса как указатели?

См. Примеры ниже:

Неправильное использование 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;
}

Отображается ошибка

/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;

Правильное использование 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;
}

1 Ответ

5 голосов
/ 07 июля 2019

Аргументы должны быть сохранены, что означает, что они скопированы.И ссылки не могут быть скопированы.

Поэтому была введена оболочка ссылок , которая может хранить ссылки, в то же время имея возможность копировать.Вы можете использовать его с вспомогательными функциями std::ref и std::cref:

std::future<int> res = std::async(&func, std::ref(ac));  // Pass ac by reference
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...