Один подход был бы к:
Другая опция состояла бы в том, чтобы удалить высокоуровневую папку и проверить снова. Надо надеяться, это не прибывает в это все же.
One thing you might wish to consider is using LLVM or similar to generate an appropriate trampoline function at runtime. Or here's a static solution:
#include <iostream>
void f(float f) { std::cout << f << std::endl; }
template<typename T, typename S> struct static_function_adapter {
template<T(*f)(S)> struct adapt_container {
static void callback(int v) {
f(static_cast<S>(v));
}
};
template<T(*f)(S)> adapt_container<f> adapt() const {
return adapt_container<f>();
}
};
template<typename T, typename S> struct static_function_adapter<T, S> get_adapter(T (*)(S)) {
return static_function_adapter<T, S>();
}
#define ADAPTED_FUNCTION(f) (&get_adapter(f).adapt<f>().callback)
int main() {
void (*adapted)(int) = ADAPTED_FUNCTION(f);
adapted(42);
return 0;
}
The get_adapter function allows us to infer the argument and return type; adapt() then converts this into a type parameterized on the actual function, and finally we get a static function in callback.
Если вы используете функцию, которая возвращает "завернутый", а не ссылается на него напрямую, компилятор попытается автоматически сопоставить параметры шаблона для вызова функции.
edit: А как насчет это?
int foobar( float x ); // wrappee
template <typename T, typename S>
struct Wrapper {
typedef T (*F)(S);
F f;
Wrapper(F f) : f(f) { }
void wrapped(S x) {
// do a bunch of other stuff here
f(x); // call wrapped function, ignore result
}
};
template <typename T, typename S>
Wrapper<T,S> getWrapper(T (*f)(S)) {
return Wrapper<T,S>(f);
}
...
getWrapper(foobar).wrapped(7);
Я бы посмотрел на повышение. При первом чтении вашего вопроса мне кажется, что
обеспечивает то, что вам нужно.
РЕДАКТИРОВАТЬ: совершенно новый ответ
Хорошо, я полностью переосмыслил вопрос и считаю, что получаю то, что вы хотите. Я уже делал это раньше :-P.
Идея в том, что у меня есть базовый класс, который перегружает operator (), а затем у меня есть подкласс для каждой "арности" функций. Наконец, у меня есть фабричная функция, которая вернет одну из этих вещей. Код большой (и, вероятно, немного избыточный), но работает хорошо. Большая часть перегрузок library_function
предназначена для поддержки различных синтаксисов, в основном ненужных. Он также поддерживает функции boost :: bind
, функции-члены и т. Д., Намного больше, чем вам, вероятно, нужно.
Пример использования:
// map of library functions which will return an int.
std::map<std::string, LibraryFunction<int> > functions;
// function to register stuff in the map
void registerFunction(const std::string &name, LibraryFunction<int> func) {
functions.insert(std::make_pair(name, func));
}
позже вы можете сделать это:
// the this param is so the function has access to the scripting engine and can pop off the parameters, you can easily chop it out
// register 2 functions, one with no params, one with 1 param
registerFunction("my_function", library_function1(*this, call_my_function));
registerFunction("my_function2", library_function0(*this, call_my_function2));
functions["my_function"]();
functions["my_function2"]();