使用默认模板参数在函数模板上获取自动推导 return 类型的指针

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

以下程序使函数 g<void>() 上的指针 x 自动推导出 return 类型:

template<class=void>
void g() {}

int main() {
    auto (*x)() = &g;
    (*x)();
}

该程序被 GCC 接受,但在 Clang 中被拒绝并出现错误:

error: variable 'x' with type 'auto (*)()' has incompatible initializer of type '<overloaded function type>'
    auto (*x)() = &g;

演示:https://gcc.godbolt.org/z/s17Mf74Wc

哪个编译器就在这里?

这个代码

auto (*x)() = &g;

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

我强调了 P1972 中添加的文本。请注意,现在如果没有指定目标类型,如 auto (*)() 的情况,因为推导了此函数的 return 类型,仍然可以执行模板参数推导。以前,在没有目标类型的情况下,在获取 g.

的地址时无法推导模板参数

当然,如果指定了g的模板参数,或者指定了目标类型,那么总是可以的

void (*x)() = &g;        // ok, target is specified
auto (*x)() = &g<void>;  // ok, template parameters specified

Clang 不支持 P1972 yet,因此出现错误。