【问题标题】:Function declaration must be available as none of the arguments depend on a template parameter函数声明必须可用,因为所有参数都不依赖于模板参数
【发布时间】:2023-01-27 23:59:27
【问题描述】:

following code 在主干 gcc 和 clang 中编译良好,但在 c++20 模式的 msvc 中失败:

template <typename T = int>
void f(void* ptr, T&& t = {}) {
    if (ptr) {
        f(nullptr);
    }
}

与消息:

error C2672: 'f': no matching overloaded function found
note: could be 'void f(void *,T &&)'
note: 'void f(void *,T &&)': could not deduce template argument for 'T'
note: 'f': function declaration must be available as none of the arguments depend on a template parameter

适用于 c++17 模式的 msvc,因为 /permissive- 仅在 c++20 之后默认可用。

可以通过显式指定模板类型(即函数主体中的f&lt;T&gt;(nullptr);)轻松修复 msvc c++20。

按照标准谁是对的?我对 c++17 和 c++20 模式都感兴趣。即将到来的 c++23 会有什么变化吗?

【问题讨论】:

  • 当打开和关闭 /permissive 标志时,错误在 C++17 标准中来来去去同样顺利。

标签: c++ templates language-lawyer


【解决方案1】:

这是CWG 2608,程序是良构的gcc 和 msvc 是符合标准.

如果可以推导出所有模板参数或者从默认的模板参数中获取,它们都可以被省略;在这种情况下,空模板参数列表 <> 本身也可以省略。

(强调我的)

这意味着 f(nullptr); 的格式正确,因为 T 的模板参数可以从默认模板参数中获得,因此它可以被省略,这意味着空模板参数列表 <> 本身也可以被省略。因此,gcc 和 clang 符合标准.另请注意,msvc 使用 /permissive 编译它,因此没有理由提交错误报告,因为他们通常建议在提交错误之前使用 /permissive 标志。


您还可以通过添加空的 &lt;&gt; 来确认这一点,您会注意到 msvc 随后会编译该程序。 Demo

template <typename T = int>
void f(void* ptr, T&& t = {}) {
    if (ptr) {
//-------vv-------------->msvc compiles this with empty <> - See CWG 2608
        f<>(nullptr);
    }
}

【讨论】:

    猜你喜欢
    • 2015-06-06
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 2016-03-24
    相关资源
    最近更新 更多