【问题标题】:Getting a pointer with auto deduced return type on function template with default template argument在具有默认模板参数的函数模板上获取具有自动推导返回类型的指针
【发布时间】:2021-12-26 20:58:32
【问题描述】:

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

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)() = &amp;g&lt;void&gt;; 通过 Demo
  • template&lt;class=void&gt; auto g() {} 失败Demo
  • void (*x)() = &amp;g; 也通过了。 Demo.
  • 即使 auto x = g; 在 clang 中失败,但在 gcc 中也可以。

标签: c++ templates language-lawyer auto


【解决方案1】:

这段代码

auto (*x)() = &g;

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

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

【讨论】:

    猜你喜欢
    • 2021-09-21
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多