当我尝试在GCC或clang中编译它时,我收到错误。
#include <cstddef>
template <void (*Function)()>
void Wrapper()
{
}
int main()
{
void (*meow)() = Wrapper<NULL>;
return meow ? 1 : 0;
}
$ g++ -m64 -std=c++11 -c nulltemplate.cpp
nulltemplate.cpp: In function ‘int main()’:
nulltemplate.cpp:10:19: error: no matches converting function ‘Wrapper’ to type ‘void (*)()’
nulltemplate.cpp:4:6: error: candidate is: template<void (* Function)()> void Wrapper()
为什么我不能这样做?错误的措辞就好像Wrapper
是一个无法在上下文中解析为特定函数指针类型的重载,这对我来说没有意义。
答案 0 :(得分:7)
NULL
是一个可以定义为(并且似乎在您的系统上)的宏:
#define NULL 0
类型为int
。所以你的代码正在进行Wrapper<0>
但是,对于作为函数指针的非类型模板参数,您必须传递实际的函数指示符或空指针值。不考虑从整数到指针的隐式转换。 0
是空指针常量,但不是空指针值。
C ++ 11引入nullptr
以避免这类问题; nullptr
不能与整数混淆。
非类型模板参数的完整条件列表以及考虑转换的列表可以在C ++标准的[temp.arg.nontype]部分找到。