The following program makes the pointer x
on function g<void>()
having automatically deduced return type:
template<class=void>
void g() {}
int main() {
auto (*x)() = &g;
(*x)();
}
The program is accepted by GCC, but rejected in Clang with the error:
error: variable 'x' with type 'auto (*)()' has incompatible initializer of type '<overloaded function type>'
auto (*x)() = &g;
Demo: https://gcc.godbolt.org/z/s17Mf74Wc
Which compiler is right here?
CodePudding user response:
This code
auto (*x)() = &g;
should be legal as per the changes made by P1972, in particular the change to temp.deduct#funaddr-1
... If there is a target, the The function template's function type and the specified target type are used as the types of P and A, and the deduction is done as described in 13.10.2.5. Otherwise, deduction is performed with empty sets of types P and A.
I've emphasized the text that was added in P1972. Note that now, if there is no specified target type, as in the case auto (*)()
since the return type of this function is deduced, template argument deduction can still be performed. Previously, without a target type, the template arguments couldn't be deduced when taking the address of g
.
Of course, if the template arguments to g
are specified, or the target type is specified, then it was always ok
void (*x)() = &g; // ok, target is specified
auto (*x)() = &g<void>; // ok, template parameters specified
Clang doesn't support P1972 yet, hence the error.