Чистая реализация шаблона функции с помощью указателя функции

Мне удалось реализовать и протестировать реализацию этой функции, однако интерфейс не так хорош, как должен быть:

template  void register_function( const char* name ) { int (*lf) (lua_State *) = function_wrapper; register_native_function( lf, name ); } 

Хотя это работает так, как ожидалось, для использования требуются явные параметры шаблона:

 register_function( "hello" ); 

Очевидно, первый параметр можно было бы вывести из первого, так что в идеале я бы хотел просто

 register_function( "hello" ); 

Является ли это возможным? Есть ли более простой способ сделать это?


Обновление : отвечая на вопрос, почему параметр templated вместо переданного:

Многие связующие (включая Lua, так как это специально предназначено для Lua) передают функции по значению:

 register_function("hello", &hello); 

Это действительно более читаемо, и со стороны интерфейса легче реализовать. Но это также означает, что адрес функции нужно где-то хранить.

Чтобы связать функцию с Lua, нам нужно, чтобы у нее был следующий прототип:

 int (*lua_CFunction) (lua_State *) 

Никакая другая информация не передается, следовательно, это запись и информация, которые мы получаем, когда связанная функция вызывается из Lua.

Если привязка выполняется во время компиляции, мы можем предоставить отдельную функцию (по шаблонам) в коде, который будет выполнен из Lua, что дает нам сопоставимую производительность для рукописных привязок, особенно если компилятор оптимизирует код шаблона.

Если привязка выполняется во время выполнения, то мы не можем создавать новые функции и вам нужна глобальная функция, которая каким-то образом знает, к какой функции следует отправлять вызов. Обычно мы не сможем получить информацию вообще, но существующие связующие Lua для компиляции Lua используют пользовательские пользовательские данные или блокировки Lua для хранения дополнительной информации, необходимой для выполнения выполнения. Тем не менее, это имеет значительный успех по сравнению с ручной привязкой из-за возможных дополнительных распределений памяти и диспетчеризации закрытия.

У меня были проблемы с исполнением версии времени исполнения в предыдущей реализации привязки (хотя и очень подчеркнутой), которая закончилась переписыванием наиболее напряженных частей в рукописные привязки и, учитывая, что на этот раз я планирую сделать lua звонки в цикле рендеринга в реальном времени, я хочу найти решение, которое будет ближе к рукописной производительности.

Если мы передадим функцию как параметр, мы, очевидно, не можем создать привязку функции во время компиляции.

Прости, Дэйв, ты не можешь этого сделать.

Были выдвинуты предложения о наличии типов шаблонов, которые впоследствии выводятся из литералов в списке типов шаблонов. Последнее, что я проверил, не собирался попасть в C ++ 1y (он же C ++ 14).

Макрос может помочь, пока язык не добавит эту функцию:

 #define REGFUNC( F ) decltype(F), (F) register_function< REGFUNC(hello) >( "hello" ); 

Также обсуждался вопрос о добавлении поддержки «lambda to C function» в C ++ (возможность принимать lambda с учетом состояния и просить ее генерировать функцию C, которая будет вызывать ее с использованием этого состояния), но я не знаю, как это происходит прогрессируют.