我要做的是创建一个模板函数,该函数存储一个通用函数指针和有关如何转换为它的实际类型的信息。我的脚本绑定API使用它来从Python为游戏引擎进行C ++函数调用。在使用带有LLVM的XCode4将其移植到OSX的过程中,我遇到了一个错误。此示例代码在Visual Studio 2012中编译并运行良好,但在LLVM中给出了错误“没有与'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的一个错误?或者是否有更好的方法来完成相同的任务?注意:函数指针必须位于模板的第一位,以便可以自动推导出函数信息。
答案 0 :(得分:3)
Clang是对的。我相信14.3.2p1排除了这个:
非类型非模板模板参数的模板参数 应该是以下之一:
- 表示地址的常量表达式(5.19) 具有静态存储持续时间和外部或内部链接的对象 或具有外部或内部联系的功能,包括 函数模板和函数template-id但不包括非静态 班级成员,表达(忽略括号)为&amp; id-expression ,除了&amp;如果名称引用,可以省略 到函数或数组,如果相应则应省略 template-parameter是一个引用;或
重要的部分是expressed (ignoring parentheses) as & id-expression
。表达式必须为&
,但不能取rvalue的地址。所以这几乎排除了任何演员阵容。
此外,从5.19p2 reinterpret_cast
在常量表达式中是非法的:
条件表达式是核心常量表达式,除非它 涉及以下之一作为潜在评估的子表达式
- reinterpret_cast(5.2.10);