Используйте умный указатель для закрытия .
std::shared_ptr<std::function<void(void)>> initf;
Затем используйте std::call_once
для его инициализации (с некоторыми лямбда-выражение ) или какой-либо конструктор stati c, инициализирующий его, например,
//untested
initf.reset (& [&] () { initf = [&]() {
auto oldinitf=initf; static int cnt;
cnt++;
std::cout << "cnt=" << cnt << std::endl;
if (oldinitf)
(oldinitf.get()) ();
});
Читайте также о Y комбинаторе с фиксированной точкой в нетипизированном λ-исчисление .
Книга Куинны c Лисп в маленьких кусочках (и Теорема Райса ) связана с вашим вопросом.
Заметьте, что циклические ссылки в памяти требуют, по крайней мере, косвенного обращения (что недружественно к подсчету ссылок подходов).
На Linux вы можете сгенерировать некоторые аналогичный код C ++ во время выполнения (с использованием необработанных указателей на функции), скомпилируйте его во временный плагин, а затем используйте dlopen
с dlsym
(я делал это несколько лет go в G CC MELT , сейчас устарел). См. C ++ dlopen minihowto и посмотрите на RefPerSys в качестве примера (программы на C ++, генерирующей и выполняющей код C ++). Посмотрите также на JIT-компиляцию библиотек, таких как libgccjit , asmjit , et c ...
Обратите внимание, что такие трюки проще с SBCL , как только вы приложите усилия для изучения Common Lisp . SBCL генерирует машинный код не более REPL взаимодействий.