Разрешено ли присвоение std :: function, которая была перемещена? - PullRequest
0 голосов
/ 18 декабря 2018

Допустим ли следующий код:

std::function<void()> CreateFunction(int i, std::function<void()> previous_f) {
   return [i,previous_f] { 
     std::cout << i << std::endl;
     previous_f();
   };
}


int main()
{
  std::function<void()> f = []{};
  for(int i=0;i<3;++i) {
    f = CreateFunction(i, f);
  }
  f();
}

Он компилируется и запускается, как и ожидалось - http://cpp.sh/2smb3,, но я обеспокоен тем, что присвоение f после перемещения f может вызвать неопределенное поведение.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Насколько это безопасно, зависит от того, передан ли объект-функция по значению или по ссылке.Как показывает ваш код, функция в «CreateFunction» передается по значению и, более того, копируется по значению в возвращаемой лямбде.

Поскольку функция была скопирована по значению, исходное значение «f»ни в коем случае не требуется разрешать вызов вновь создаваемой функции.

Как примечание, может быть лучше использовать получение const-ссылки внутри CreateFunction, так как это минимизирует количество раз, которое функцияобъект копируется по значению.

0 голосов
/ 18 декабря 2018

Поскольку вы фиксируете по значению в лямбде ([i, previous_f] делает копию previous_f, полностью отсоединенную от переданного вами параметра), она будет действительной.В конце концов, f (косвенно, в контексте лямбды) будет содержать копии всех функций.

Обратите внимание, что вы не используете std::move.Однако даже в этом случае все равно будет хорошо, если вы будете делать копии, не заботясь о том, что оригинал previous_f был уничтожен.

...