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

Fed*_*dor 5 c++ templates language-lawyer auto

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

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

int main() {
    auto (*x)() = &g;
    (*x)();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

这里是哪个编译器?

cig*_*ien 4

这段代码

auto (*x)() = &g;
Run Code Online (Sandbox Code Playgroud)

根据P1972所做的更改应该是合法的,特别是对temp.deduct#funaddr-1的更改

...如果有目标,则将函数模板的函数类型和指定的目标类型作为P和A的类型,并按13.10.2.5所述进行推导。否则,用类型 P 和 A 的空集进行推导。

我已经强调了 P1972 中添加的文本。请注意,现在如果没有指定目标类型,就像auto (*)()推导该函数的返回类型一样,仍然可以执行模板参数推导。以前,如果没有目标类型,则在获取 的地址时无法推导模板参数g

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

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

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