В чем причина ошибки std@bad_function_call при создании потока

Есть следующий код:

std::function<void()> f=[](){std::cout<<"Yaha";};

std::thread thr1(f);
std::thread thr2(f); //Здесь возникает ошибка std@bad_function_call

Прошу подсказать причину возникновения данной ошибки. Как я понимаю объект f становится пустым (не пойму почему).

И второй вопрос:

void thr1_f()
 {
  std::cout<<"Yaha"; 
 }

в чем разница в std::thread(thr1_f) и std::thread(&thr1_f) и когда какой вариант следует использовать? Почему нельзя вызвать std::thread(&f) (а нужно использовать std::thread(std::ref(f))?

Заранее благодарю!


Ответы (1 шт):

Автор решения: KoVadim

std@bad_function_call можно получить, если внутри фукнции лежит nullptr.

Смотрим снова в документацию и видим такое

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

ага, нужно, что бы move конструктор отработал и можно получить такой эффект. Так как автор вопроса упоминает о передаче по ссылке и по std::ref, сделаем маленький шаг в сторону

std::function<void()> f=[](){std::cout<<"Yaha";};

std::thread thr1(std::move(f));
std::thread thr2(f); 
thr1.join();
thr2.join();

и получим желаемую ошибочку. std::move провоцирует вызов move конструктора, который в случае std::function зануляет указатель.

А возможно, компилятор у Embarcadero RAD Studio такой хитрый, что вызывает move конструктор. или там сам std::thread объявлен с std::forward, надо смотреть в сам код. я этого проверить не могу.

→ Ссылка