我有一个标题,我在其中放置了函数模板的定义:
template <typename FT, typename std::enable_if< !std::is_array<FT>::value, int >::type =0 >
int fieldRW(lua_State* l, FT* ptr, bool write){ return scalarFieldRW<FT>(l, ptr, write); }
在.cpp单元中我得到一个指向这个模板函数的指针,我希望编译器实例化模板:
typedef int (*_fieldRW)(lua_State*, void*, bool);
int dummy=3;
_fieldRW aFunctionPointer=_fieldRW(fieldRW<decltype(dummy)>);
一切都在编译。但是我收到以下链接时错误:
/home/pisto/sorgenti/hopmodv4/src/fpsgame/server.cpp:39:undefined 引用`int fieldRW(lua_State *,int *,bool)'
请注意,编译器正确选择了标头中定义的模板(因为它添加了模板的默认第二个参数),但显然它无法实际实例化模板。
编辑: 这看起来绝对像一个bug。请参阅以下测试:http://pastebin.com/5Yjsv47H 此外,另一个线索,这可能是g ++中的一个错误,如果我这样做:
int main() {
int dummy=3;
int (*inted)(int*)=asd<decltype(dummy)>;
int (*voided)(void*)=(int (*)(void*))asd<decltype(dummy)>;
voided(&dummy);
}
g ++警告未使用的变量inted
,但编译得很好。
答案 0 :(得分:1)
答案可能是函数指针转换规范中的一个微妙之处:
标准在[expr.reinterpret.cast]中说明 “函数指针可以显式转换为a的函数指针 不同的类型。通过指针调用函数的效果 函数类型(8.3.5)与定义中使用的类型不同 该函数未定义。“
所以我认为程序有不确定的行为。因为你从不打电话 作为有效表达式的一部分,它不需要实例化。
Clang ++以与G ++ 4.6相同的方式失败,但它适用于G ++ 4.7
(感谢Jonathan Wakely)