Ответ 1
Это законно с указателями функций.
Когда вы назначаете или создаете std::function
с целью, он создает копию цели. В случае назначения функции std::function
, это фактически сохраняет указатель функции в качестве целевого объекта.
При вызове operator()
требуется вернуть то, что произойдет, если вы вызовете цель с аргументами.
Внутри этого "тела" копии объекта функции, сохраненного как копия в std::function
, если вы переназначаете на std::function
, это уничтожит старый объект целевой функции.
Уничтожение указателя функции не влияет на достоверность кода, выполняемого в указанной функции.
Однако, если вы сохранили объекты функции (lambdas, manual, другие std::function
s, std::bind
и т.д.), то в точке назначения вы столкнулись с обычными правилами запуска метода в классе когда this
уничтожается. Короче говоря, вы больше не сможете делать ничего, что полагалось бы на "локальное состояние" вашего экземпляра.
std::function<void()> fun;
struct bob {
std::string name;
bob* next = 0;
void operator()() const {
std::cout << name << "\n";
if (next) fun = *next;
// undefined behavior:
// std::cout << name << "\n";
}
};
bob foo = {"foo"};
bob bar = {"bar", &foo};
int main() {
fun = bar;
fun();
fun();
}
Итак, как вы можете видеть, это может быть хрупким.