обновление 2
Ладно, разобрался со второй проблемой. Как указывалось ранее, у меня возникла конфликтная ошибка с точки зрения соответствия ReturnType(Args...)
против ReturnType (*)(Args..)
, Очевидное решение заключается в следующем:
template <typename F, F *fn>
void doSomething() {
function_helper<F>::template toNative<fn>();
}
и теперь он компилируется под Clang ++.
Обновить
Как было указано, у меня была проблема с моим предыдущим кодом, когда я пытался передать параметр функции в параметр шаблона. Тем не менее, это было скрыто чужой ошибкой разбора ошибки. Неправильная передача параметра функции не должна была привести к ошибке, которую я увидел.
Оказывается, проблема заключалась в новом синтаксисе для вызова шаблонной функции-члена класса (см. http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/keyword_template_qualifier.htm).
Правильный синтаксис должен быть:
template <typename F, F *fn>
void doSomething() {
native_function native = function_helper<decltype(fn)>::template toNative<fn>();
}
где шаблон должен быть вставлен между ‘::’ и функцией.
К сожалению, это очень сложная проблема поиска, так как: (а) ошибка компилятора совершенно бесполезна, и (б) не было очевидного поискового термина для использования.
Кроме того, в настоящее время это, похоже, не работает ни в текущей версии clang ++, ни в g ++ 4.6 (пока что я получаю еще одну синтаксическую ошибку или внутреннюю ошибку компилятора).
оригинальный вопрос
В продолжение моего предыдущий вопрос, У меня есть следующий код:
template <typename T>
struct function_helper {};
template <typename ReturnType, typename... Args>
struct function_helper<ReturnType(Args...)> {
// wraps actual function in a native-c function (allow it to be called
// via an external scripting language API)
template <ReturnType (*fn)(Args...)>
static native_function toNative() {
return [](State *state) -> int {
Context ctx(state);
return apply_helper<sizeof...(Args)>::apply(ctx, fn);
};
}
};
который я хотел бы обернуть:
template <typename ReturnType, typename... Args>
native_function function_(Context &ctx, const std::string &name, ReturnType (*fn)(Args...)) {
ctx.registerFn(name, function_helper<decltype(fn)>::toNative<fn>());
}
Тем не менее, это дает мне «Ошибка разбора». Если я не пытаюсь обернуть это в функцию, а вместо этого сделаю:
int main(int argc, char **argv) {
// ...
ctx.registerFn("myFunc", function_helper<decltype(myFunc)>::toNative<myFunc>());
}
все компилируется и работает правильно. Аналогично, если я использовал макрос, он также работает. Однако по причинам дизайна я бы предпочел использовать функцию.
Я также попробовал немного другую формулировку, с теми же результатами:
template <typename T>
struct function_args {};
template <typename ReturnType, typename... Args>
struct function_args<ReturnType (*)(Args...)> {
const int size = sizeof...(Args);
};
template <typename F, F *fn>
native_function wrap() {
return [](State *state) -> int {
Context ctx(state);
return apply_helper<function_args<decltype(fn)>::size>::apply(ctx, fn);
};
}
Я делаю что-то не так или это проблема с компилятором? Ошибка разбора делает меня подозрительным, что виноват компилятор.
Я мог бы избавиться от ошибки разбора, добавив параметр toNative (). Тем не менее, это просто вызвало другую ошибку, что не было такого метода toNative (int).
Я использую последний Clang ++, который поставляется с XCode (на основе LLVM 3.1svn).
Задача ещё не решена.
Других решений пока нет …