αλε*_*λυτ 8 c++ templates language-lawyer
以下代码在 trunk gcc 和 clang 中编译良好,但在 msvc for c++20 模式下编译失败:
template <typename T = int>
void f(void* ptr, T&& t = {}) {
if (ptr) {
f(nullptr);
}
}
Run Code Online (Sandbox Code Playgroud)
与消息:
Run Code Online (Sandbox Code Playgroud)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<T>(nullptr);对于 msvc c++20,可以通过显式指定模板类型(即在函数体中)轻松修复。
按照标准,谁是对的?我对 c++17 和 c++20 模式都感兴趣。即将推出的 c++23 是否会有任何变化?
这是CWG 2608,该程序格式良好,并且 gcc 和 clang符合标准。
如果所有模板参数都可以从默认模板参数中推导或获得,则可以全部省略;在这种情况下,空模板参数列表 <> 本身也可以被省略。
(强调我的)
这意味着f(nullptr);是格式良好的,因为模板参数 forT可以从默认模板参数获得,因此它可以被省略,这意味着空模板参数列表 <> 本身也可以被省略。因此,gcc 和 clang 是符合标准的。另请注意,msvc 对此进行编译/permissive,因此没有理由提交错误报告,因为他们通常建议/permissive在提交错误之前使用标志。
您还可以通过添加空来确认这一点<>,然后您会注意到 msvc 会编译该程序。演示
template <typename T = int>
void f(void* ptr, T&& t = {}) {
if (ptr) {
//-------vv-------------->msvc compiles this with empty <> - See CWG 2608
f<>(nullptr);
}
}
Run Code Online (Sandbox Code Playgroud)