Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function-to-pointer implicit conversion: which compiler is right? Clang and GCC disagree

Tags:

c++

gcc

clang

template <typename Type, Type Func>
struct A
{
};

void func();

A<void(), func> a; // same result with A<void(), &func> a;

This code compiles with Clang (including latest 8.0.0), but not with GCC (including latest 9.1).

GCC says: error: 'void()' is not a valid type for a template non-type parameter

Which compiler is right and why?

Update

I am guessing GCC is wrong, because the following compiles on both Clang and GCC:

template <void()>
struct A
{
};

void func();

A<func> a; // same result with A<&func> a;

So contrary to what GCC reports in the first example, void() seems to be "a valid type for a template non-type parameter"

like image 916
Boris Rasin Avatar asked Jun 07 '19 17:06

Boris Rasin


1 Answers

Similarly to what happens to function parameter type, if the type of a non-type template parameter is a function type, it is adjusted to pointer to function type [temp.param]/8:

A non-type template-parameter of type “array of T” or of function type T is adjusted to be of type “pointer to T”.

So clang is right. GCC bug report already exists bug #82773


Only the current working draft of the c++ standard recognizes the process of substitution of template argument into following template parameters. So it could be argued that the standard is not clear because it does not specify that the type adjustment is performed after each of those substitutions.

like image 63
Oliv Avatar answered Nov 20 '22 11:11

Oliv