Это связано с тем, что ни один из создаваемых вами объектов на самом деле не является функцией std ::, они могут быть вызваны для создания временных функций std :: functions. И последнее, насколько мне известно (например, я не утверждаю, что это правда, я предполагаю, что из-за моей лени, см. Ниже), это UB, так как перемещенный из объекта может быть оставлен в любом допустимом состоянии, поэтому нет гарантирует, что строковый член действительно будет пустым.
Как правило, используйте перемещенные объекты таким образом, чтобы не требовалось никаких предварительных условий (переназначить, проверить, не заполнены ли строки / vec и т. Д.).
Чтобы уточнить, давайте посмотрим на конструкторы std :: function здесь , рассматриваемый конструктор (5):
template< class F >
function( F f );
Поэтому, когда вы пытаетесь создать функцию std :: с вызываемой функцией, вы по умолчанию создаете копию вызываемой. Вы обходите это, например используя std :: ref, что приведет к тому, что последующие изменения вызываемого объекта будут отражены в std :: function с его использованием (как тогда вы на самом деле создаете «из ref», а не из копирования как обычно).