gpt4 book ai didi

c++ - 获取地址时推导函数模板特化

转载 作者:行者123 更新时间:2023-12-05 03:23:27 24 4
gpt4 key购买 nike

我试图理解在所有参数都默认的情况下函数模板参数推导的规则。在 13.10.1(显式模板参数规范)下,标准 (C++20) 说:

——当获取函数的地址时,当函数初始化函数的引用时,或者当形成指向成员函数的指针时,...如果可以推导出所有模板参数,则可以将它们全部省略;在这种情况下,空模板参数列表 <> 本身也可以省略。

但是,在下面代码片段的第四行中,编译器(gcc、MSVC)似乎坚持使用空尖括号。这是不符合规定还是我错过了什么? (在这个例子中,问题并不重要,但问题是在它确实重要的上下文中出现的)。

template <typename T = int> void f(T) {}
void (*p)(int) = f; //ok
auto a = f<>; //ok
auto b = f; //error, can't deduce

void g() {}
auto c = g; //OK

最佳答案

编译器是正确的:auto a = f<>;格式正确并且auto b = f;是病式的。这是由于关于 auto 的规则。 , 结合函数模板名称的地址规则 f .

[dcl.type.auto.deduct]/4 中所述, auto变量定义的类型以类似于在其函数参数中使用模板类型参数为假设函数模板完成的模板参数推导的方式找到:

template <typename U> void auto_deducer(U);
auto a = f<>; // auto becomes the U deduced for auto_deducer(f<>)
auto b = f; // auto becomes the U deduced for auto_deducer(f)

[temp.deduct.type]第 4 和第 5 段:

In certain contexts, however, the value [of a template argument] does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

The non-deduced contexts are:

  • ...
  • A function parameter for which the associated argument is an overload set, and one or more of the following apply:
    • ...
    • the overload set supplied as an argument contains one or more function templates.
  • ...

所以对于ab ,用于确定 auto 类型的模板参数推导失败。由于“可以推导出所有模板参数”是不正确的,因此我们不允许省略空的 <>。语法。

但我们还没有完全完成,因为同一个段落[temp.arg.explicit]/4你引用的有一些相关的附加文本:

Trailing template arguments that can be deduced or obtained from default template-arguments may be omitted from the list of explicit template-arguments. A trailing template parameter pack.... If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted. In contexts where deduction is done and fails, or in contexts where deduction is not done, if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.

对于a两者的定义和 b , f<>f表达式处于非推导上下文中,因此“推导未完成”。 (假设的 auto_deducer(f<>) 的模板参数推导失败,但这是针对整个 auto_deducer 调用,在实际涉及 f<> 的部分确定类型推导步骤根本不应该使用该参数完成之后。)在auto a = f<>; ,“指定了模板参数列表”并使用默认模板参数“标识单个函数模板特化”f<int> , 因此段落的最后一句话适用并且 template-id 名称为 f<int>毕竟。在 auto b = f;未指定模板参数列表(并且 f 不是 template-id),因此该句子不适用。

实际的调用就像语句 f();很好,因为会发生模板参数推导,使用默认模板参数,并且在没有 auto 的复杂情况下成功.转换表达式 f指向特定目标函数指针类型很好,因为这将推导出模板参数 T来自目标类型,并且不涉及默认模板参数。

[over.over]/3 中的非规范性说明中可以找到此行为的另一确认信息。 . [over.over] 部分适用于查找名称(如 ff<> )给出包含一个或多个函数和/或函数模板的重载集并且名称表达式后面没有函数调用参数列表:

For each function template designated by the name, template argument deduction is done, and if the argument deduction succeeds, the resulting template argument list is used to generate a single function template specialization, which is added to the set of selected functions considered. [ Note: As described in [temp.arg.explicit], if deduction fails and the function template name is followed by an explicit template argument list, the template-id is then examined to see whether it identifies a single function template specialization. If it does, the template-id is considered to be an lvalue for that function template specialization. The target type is not used in that determination. - end note ]

关于c++ - 获取地址时推导函数模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72519217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com