函数指针 vs 函数作为模板非类型参数
Pointer to function vs function as template non-type parameter
我试图了解以下代码段中发生的事情:
// using FUN = void(*)(void);
using FUN = void(void);
template<FUN fun> struct Fun{};
int main ()
{
FUN fun;
Fun<fun>{};
}
我可以使用void(void)
作为函数非类型参数,一切正常,程序编译通过。但是,将类型更改为指向函数的指针,即删除第一行中的注释并注释第二行,会导致错误
(g++) error: the value of 'fun' is not usable in a constant expression
(clang) error: non-type template argument of type 'FUN' (aka 'void (*)()')
is not a constant expression
到底是怎么回事?函数类型实际上与指向函数的指针不同吗(即,在任何地方都可以隐式转换?)我知道指向函数的指针不应该起作用,因为 FUN fun;
在 main
中它不是常量表达式,但为什么将 FUN
声明为 void(void);
使其起作用?
A non-type template-parameter of type “array of T
” or “function returning T
” is adjusted to be of type
“pointer to T
” or “pointer to function returning T
”, respectively.
(C++14 中的[temp.param]/8)
因此,模板 Fun
是同一个模板,无论 FUN
被声明为函数还是指向函数类型的指针。
但是,这个块声明:
FUN fun;
根据 FUN
的不同有不同的含义。如果 FUN
是函数,则这是函数的块声明(如果使用 odr,则必须在其他地方定义)。通常,您可以使用函数的名称作为函数指针类型的模板参数的参数——这里没有问题。但是如果 FUN
是一个函数指针,这将创建一个未初始化的函数指针。因为它是一个非 const
对象,所以它不能用作模板参数,就像 int
变量不能用作 int
模板参数但 const int
变量可以.
我试图了解以下代码段中发生的事情:
// using FUN = void(*)(void);
using FUN = void(void);
template<FUN fun> struct Fun{};
int main ()
{
FUN fun;
Fun<fun>{};
}
我可以使用void(void)
作为函数非类型参数,一切正常,程序编译通过。但是,将类型更改为指向函数的指针,即删除第一行中的注释并注释第二行,会导致错误
(g++) error: the value of 'fun' is not usable in a constant expression
(clang) error: non-type template argument of type 'FUN' (aka 'void (*)()') is not a constant expression
到底是怎么回事?函数类型实际上与指向函数的指针不同吗(即,在任何地方都可以隐式转换?)我知道指向函数的指针不应该起作用,因为 FUN fun;
在 main
中它不是常量表达式,但为什么将 FUN
声明为 void(void);
使其起作用?
A non-type template-parameter of type “array of
T
” or “function returningT
” is adjusted to be of type “pointer toT
” or “pointer to function returningT
”, respectively.
(C++14 中的[temp.param]/8)
因此,模板 Fun
是同一个模板,无论 FUN
被声明为函数还是指向函数类型的指针。
但是,这个块声明:
FUN fun;
根据 FUN
的不同有不同的含义。如果 FUN
是函数,则这是函数的块声明(如果使用 odr,则必须在其他地方定义)。通常,您可以使用函数的名称作为函数指针类型的模板参数的参数——这里没有问题。但是如果 FUN
是一个函数指针,这将创建一个未初始化的函数指针。因为它是一个非 const
对象,所以它不能用作模板参数,就像 int
变量不能用作 int
模板参数但 const int
变量可以.