Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a pointer with auto deduced return type on function template with default template argument

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?

like image 248
Fedor Avatar asked Dec 26 '21 20:12

Fedor


1 Answers

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.

like image 148
cigien Avatar answered Oct 17 '22 09:10

cigien