3

我要做的是创建一个模板函数,该函数存储通用函数指针和有关如何转换为实际类型的信息。我的脚本绑定 API 使用它从 Python 为游戏引擎进行 C++ 函数调用。在使用带有 LLVM 的 XCode4 将其移植到 OSX 的过程中,我遇到了一个错误。此示例代码在 Visual Studio 2012 中编译并运行良好,但使用 LLVM 时出现错误“No matching function for call to 'Call'”。

#include <iostream>

void testfun (int i)
{
  std::cout << "Hello World " << i << std::endl;
}

typedef void BasicFunction ();

template <BasicFunction* fn, typename T0>
void Call (void(*f)(T0), T0 i)
{
  reinterpret_cast<decltype(f)>(fn)(i);
}

int main(int argc, const char * argv[])
{
  Call<reinterpret_cast<BasicFunction*>(testfun)>(testfun, 5);
  return 0;
}

这是非标准代码吗?LLVM 的错误?还是有更好的方法来完成相同的任务?注意:函数指针必须在模板中排在第一位,这样才能自动推导出函数信息。

4

1 回答 1

3

叮当是正确的。我相信 14.3.2p1 排除了这一点:

非类型、非模板模板参数的模板参数应为以下之一:

— 一个常量表达式 (5.19),它指定具有静态存储持续时间和外部或内部链接的对象或具有外部或内部链接的函数的地址,包括函数模板和函数模板 ID,但不包括非静态类成员,表示为 (忽略括号)作为 & id-expression,但如果名称引用函数或数组,则 & 可以省略,如果相应的模板参数是引用,则应省略;或者

重要的部分是expressed (ignoring parentheses) as & id-expression。表达式必须有一个&,但是您不能获取右值的地址。所以这几乎排除了任何演员表。

此外,从 5.19p2 开始reinterpret_cast在常量表达式中是非法的:

条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式

— reinterpret_cast (5.2.10);

于 2013-04-14T21:43:24.933 回答