简体   繁体   English

函数指针与作为模板非类型参数的指针

[英]Pointer to function vs function as template non-type parameter

I am trying to understand what's going on in the following snippet: 我试图了解以下代码段中发生的情况:

// using FUN = void(*)(void);
using FUN = void(void);

template<FUN fun> struct Fun{};

int main ()
{
    FUN fun;
    Fun<fun>{};
}

I can use void(void) as a function non-type parameter, everything is fine, the program compiles. 我可以将void(void)用作函数非类型参数,一切都很好,程序可以编译。 However, changing the type to pointer to function, ie removing the comment in the first line and commenting the second line, results in the error 但是,将类型更改为函数指针,即删除第一行中的注释并注释第二行,将导致错误

( g++ ) error: the value of 'fun' is not usable in a constant expression g ++ )错误:“ fun”的值在常量表达式中不可用

( clang ) error: non-type template argument of type 'FUN' (aka 'void (*)()') is not a constant expression clang )错误:类型为'FUN'的非类型模板参数(aka'void(*)()')不是常量表达式

What exactly is going on? 到底是怎么回事? Isn't a function type actually the same as a pointer to function (ie, implicitly convertible everywhere?) I understand that the pointer to function shouldn't work, since FUN fun; 函数类型实际上与指向函数的指针不一样吗(即,在任何地方都可以隐式转换吗?)我知道指向函数的指针不应该起作用,因为这FUN fun; in main it's not a constant expression, but why does declaring FUN as void(void); main它不是一个常量表达式,但是为什么将FUN声明为void(void); make it work? 让它起作用?

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. 类型“阵列的非类型模板参数T ”或“函数返回T ”被调整为类型“指针的T ”或“指针函数返回T分别”,。

([temp.param]/8 in C++14) (在C ++ 14中为[temp.param] / 8)

Therefore the template Fun is the same template regardless of whether FUN is declared to be a function or pointer to function type. 因此,模板Fun是相同的模板,而不管FUN是声明为函数还是指向函数类型的指针。

But, this block declaration: 但是,此块声明:

FUN fun;

has a different meaning depending on what FUN is. 根据FUN是什么,其含义有所不同。 If FUN is a function, this is a block declaration of a function (which, if odr-used, must be defined somewhere else). 如果FUN是一个函数,则这是一个函数的块声明(如果使用odr,则必须在其他地方定义)。 Generally, you can use the name of a function as an argument to a template parameter of type pointer to function---no issues here. 通常,您可以将函数的名称用作函数类型的指针的模板参数的参数-此处没有问题。 But if FUN is a function pointer, this creates an uninitialized function pointer. 但是,如果FUN是函数指针,则会创建一个未初始化的函数指针。 Since it's a non- const object, it cannot be used as a template argument, just as an int variable cannot be used as a template argument for an int template parameter but a const int variable can. 由于它是一个非const对象,因此不能用作模板参数,就像int变量不能用作int模板参数的模板参数一样,而const int变量也可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM