简体   繁体   中英

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. 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

( clang ) error: non-type template argument of type 'FUN' (aka 'void (*)()') is not a constant expression

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; in main it's not a constant expression, but why does declaring FUN as 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.

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

Therefore the template Fun is the same template regardless of whether FUN is declared to be a function or pointer to function type.

But, this block declaration:

FUN fun;

has a different meaning depending on what FUN is. If FUN is a function, this is a block declaration of a function (which, if odr-used, must be defined somewhere else). 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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