在所有参数都是默认的情况下,我试图理解函数模板参数推导的规则。在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发布于 2022-06-08 01:42:05
编译器是正确的: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段:
但是,在某些上下文中,模板参数的值不参与类型推导,而是使用在其他地方推导或显式指定的模板参数的值。如果模板参数仅在非推导上下文中使用,且未显式指定,则模板参数演绎失败。 未推导的上下文如下:
因此,对于a和b,用于确定auto类型的模板参数演绎失败。由于“所有模板参数都可以推导”的说法并不正确,所以我们不允许省略空的<>语法。
但是我们还没有完全完成,因为[temp.arg.explicit]/4引用的同一段有一些相关的附加文本:
可以从默认模板推断或获得的尾随模板参数--参数可以从显式模板参数列表中省略。尾随模板参数包..。如果可以推导出所有的模板参数,那么它们都可以被省略;在这种情况下,空模板参数列表
<>本身也可能被省略。在进行演绎并失败的上下文中,或者在不进行演绎的上下文中,如果指定了模板参数列表,并与任何默认模板参数一起标识单个函数模板专门化,则模板id是函数模板专门化的lvalue。
对于a和b的定义,f<>或f表达式是在一个非推导的上下文中,因此“演绎是不做的”。(然后,假设的auto_deducer(f<>)的模板参数推导失败,但对于整个auto_deducer调用来说,在实际涉及f<>的部分确定不应该使用该参数执行类型推断步骤之后,就会失败。)在auto a = f<>;中,“指定了模板参数列表”,并使用默认的模板参数“标识单个函数模板专门化”f<int>,因此段落的最后一句适用,模板id名称f<int>毕竟也适用。在auto b = f;中没有指定模板参数列表(并且f不是模板id),所以这个句子不能应用。
像语句f();这样的实际调用是可以的,因为模板参数的推导发生了,使用了默认的模板参数,并且成功了,而没有auto的复杂性。将表达式f转换为特定的目标指针到函数类型很好,因为这将从目标类型中推导出模板参数T,并且不会涉及默认的模板参数。
这一行为的另一种确认是在[over.over]/3中的一个非规范性说明中找到的。当查找一个名称(如over.over或f<>)提供一个包含一个或多个函数和/或函数模板的重载集,并且名称表达式后面没有函数调用参数列表时,就可以使用该名称部分:
对于由名称指定的每个函数模板,将执行模板参数演绎,如果参数演绎成功,则使用生成的模板参数列表生成单个函数模板专门化,将其添加到所选函数集中。[注意:正如在temp.arg.explicit中所描述的,如果演绎失败,并且函数模板名称后面跟着一个显式模板参数列表,那么模板-id就会被检查,以确定它是否识别单个函数模板专门化。如果是这样,模板id将被视为该函数模板专门化的一个lvalue。在该确定中不使用目标类型。-尾注]
发布于 2022-06-07 16:55:18
可以从默认模板推断或获得的尾随模板参数--参数可以从显式模板参数列表中省略。..。如果可以推导出所有的模板参数,那么它们都可以被省略;在这种情况下,空模板参数列表<>本身也可能被省略。
注意,与第一句相反,最后一句并没有说“从默认模板-参数中推断或获得”。从默认模板中推断和获取参数是两件不同的事情。这可能是也可能不是标准中的措词缺陷。
https://stackoverflow.com/questions/72519217
复制相似问题