简体   繁体   English

Function 声明必须可用,因为 arguments 都不依赖于模板参数

[英]Function declaration must be available as none of the arguments depend on a template parameter

The following code compiled well in trunk gcc and clang, but failed in msvc for c++20 mode:以下代码在 trunk gcc 和 clang 中编译良好,但在 msvc for c++20 模式中失败:

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

with the messages:与消息:

 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

Works well for msvc for c++17 mode, since /permissive- is only available by default since c++20.适用于 c++17 模式的 msvc,因为/permissive-自 c++20 以来仅在默认情况下可用。

Can be easily fixed for msvc c++20 by specifying template type explicitly, ie f<T>(nullptr);可以通过显式指定模板类型轻松修复 msvc c++20,即f<T>(nullptr); in the function body.在 function 正文中。

Who is right according to the standard?按照标准谁是对的? I'm interested for both c++17 and c++20 modes.我对 c++17 和 c++20 模式都感兴趣。 Is there any changes will come with upcoming c++23?即将到来的 c++23 会有什么变化吗?

This is CWG 2608 and the program is well-formed and gcc and clang are standard conformant .这是CWG 2608 ,程序格式正确,gcc 和 clang 符合标准

If all of the template arguments can be deduced or obtained from default template-arguments, they may all be omitted ;如果所有模板 arguments 都可以从默认模板参数中推导出或获得,则可以将它们全部省略 in this case, the empty template argument list <> itself may also be omitted.在这种情况下,空模板参数列表 <> 本身也可以省略。

(emphasis mine) (强调我的)

This means that f(nullptr);这意味着f(nullptr); is well-formed as the template argument for T can be obtained from the default template argument and hence it may be omitted which implies that the empty template argument list <> itself may also be omitted.格式正确,因为T的模板参数可以从默认模板参数获得,因此它可以被省略,这意味着空模板参数列表 <> 本身也可以被省略。 Thus, gcc and clang are standard conformant .因此, gcc 和 clang 是符合标准的 Note also that msvc compiles this with /permissive so there is no reason to submit a bug report since they usually advise to use /permissive flag before submitting bugs.另请注意,msvc 使用/permissive编译它,因此没有理由提交错误报告,因为他们通常建议在提交错误之前使用/permissive标志。


You can also confirm this by adding empty <> and you will notice that msvc then compiles the program.您还可以通过添加空<>来确认这一点,您会注意到 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);
    }
}

This is a bug with MSVC.这是 MSVC 的错误。

It is contrary to [dcl.fct.default]p9 :它与[dcl.fct.default]p9相反:

When an overload set contains a declaration of a function that inhabits a scope S , any default argument associated with any reachable declaration that inhabits S is available to the call.当重载集包含位于 scope S的 function 的声明时,与位于S的任何可达声明关联的任何默认参数都可用于调用。

Where the associated default arguments are reachable as soon as they are declared.关联的默认值 arguments 在声明后立即可用。

MSVC does not seem to be able to find the default arguments directly after they are declared, but only after the entire definition of the function. MSVC 似乎无法在声明后直接找到默认的 arguments,但只能在 function 的整个定义之后找到。

When you split off the declaration for the defaults:当您拆分默认值的声明时:

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

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

(Or turn off MSVC's two phase lookup with /Zc:twoPhase- , or "trick" the two-phase lookup by adding a dummy using::f; or writing f<>(nullptr) instead) (或者使用/Zc:twoPhase-关闭 MSVC 的两阶段查找,或者通过using::f;或者改为编写f<>(nullptr)

Then the declaration for the default arguments can be seen and it will be called properly.然后可以看到默认arguments的声明,它会被正确调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误:“at”没有依赖于模板参数的参数,因此at的声明必须可用 - error: there are no arguments to 'at' that depend on a template parameter, so a declaration of at must be available g ++:错误:“ pow”没有依赖模板参数的参数,因此“ pow”的声明必须可用[-fpermissive] - g++: error: there are no arguments to 'pow' that depend on a template parameter, so a declaration of 'pow' must be available [-fpermissive] 没有依赖于模板参数的参数 - There are no arguments that depend on a template parameter 如何解决“没有依赖模板参数的&#39;glGenVertexArrays&#39;参数……”在C ++中的错误 - How to fix 'there are no arguments to 'glGenVertexArrays' that depend on a template parameter …' error in c++ C ++错误:“没有&#39;setw&#39;参数依赖模板参数 - C++ Error: "There are no arguments to 'setw' that depend on a template parameter mex编译给出“……没有依赖模板参数的参数”错误 - mex compilation gives “there are no arguments to … that depend on a template parameter” error 错误:“static_assert”没有依赖于模板参数的参数 - Error: there are no arguments to 'static_assert' that depend on a template parameter 省略号出现在模板函数的参数声明中 - Ellipsis appears in a parameter declaration of a template function 以参数作为模板参数的模板化函数指针 - Templated function pointer with arguments as template parameter 模板参数 - 具有可变参数的函数指针 - Template parameter - function pointer with variadic arguments
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM