Я прохожу учебники по TensorFlow и, копаясь в коде, я наткнулся на это:
OpDefBuilder& RegisterOp(StringPiece name) {
VLOG(1) << "RegisterOp: " << name;
OpDefBuilder* b = new OpDefBuilder(name);
OpRegistry::Global()->Register([b]() -> ::tensorflow::OpDef {
OpDef op_def;
TF_QCHECK_OK(b->Finalize(&op_def));
delete b;
return op_def;
});
return *b;
}
Объявление функции Register выглядит следующим образом:
void OpRegistry::Register(std::function<OpDef(void)> func);
Вышеупомянутый фрагмент, кажется, создает OpDefBuilder*
объект с OpDefBuilder* b = new OpDefBuilder(name);
Затем он уничтожает этот объект с delete b;
внутри лямбда-функции, передаваемой в качестве аргумента OpRegistry::Global()->Register(...)
, И тогда он возвращает тот же объект (!). Предполагая, что лямбда-функция вызывается в Register(...)
(и это называют в соответствии с моим пониманием), это не имеет смысла для меня.
Я не новичок в C ++, но я никогда не видел подобной практики раньше. Что мне здесь не хватает?
Полный файл .cpp (включая Register(...)
определение) Вот
Ваша помощь будет принята с благодарностью.
Конструктор OpDef
устанавливает initialized
участник false
, Однако объект функции передан Register
вызывается только когда этот член true
, То есть регистрация не вызывает функцию delete
Инг объект.
Предположительно, функция выполняется позже, после чего объект очищается. Эта часть выглядит для меня несколько сомнительно, но, не копаясь намного глубже, не кажется очевидной ошибкой.
Трудно сказать без кода для Register
, но скорее всего он не выполняет лямбда, переданную ему сразу. Это, вероятно, хранит его для выполнения позже, в качестве некоторой очистки.
Я на 90% убежден, что это настоящая ошибка. Я копаюсь в этом с помощью некоторых людей, которые лучше разбираются в операционном реестре. Буду обновлять.
(Я считаю, что при каждом использовании реестра, initialized_
имеет значение false, т. е. все операции регистрируются до выполнения каких-либо поисков или других операций в реестре. Этот путь, очевидно, является правильным, поскольку операция добавляется в отложенную очередь, поэтому удаление не вступит в силу до более позднего периода. Тем не менее, он пахнет как ошибка, если операция зарегистрирована позже. Это то, что я проверяю и пытаюсь создать контрольный пример.)