【问题标题】:是否有规定在函数模板显式特化中指定对“返回类型”的限制?
【发布时间】:2022-01-23 15:18:51
【问题描述】:
template<class T>
void fun(T){}

template<>
int fun(int){return 0;}

考虑这个例子,所有实现都是rejected。但是,我在当前标准中没有找到任何有说服力的条款来指定这个明确的专业化声明是格式错误的。如果存在,规则是什么?

此外,潜在的相关规则可能是 [temp.deduct.decl#2]

如果对于这样考虑的一组函数模板,在考虑了部分排序([temp.func.order])之后没有匹配或多个匹配,则推导失败并且,在声明的情况下,程序是非良构的。

我认为“匹配”的含义在这里不够清楚,因为“匹配”没有明确定义任何东西。

【问题讨论】:

  • 如果允许,static_cast&lt;void(*)(int)&gt;(&amp;fun) 会做什么?编译器会先成功推导出T = int,然后找到特化,然后将特化函数的类型与强制转换中的类型进行比较?
  • @HolyBlackCat:好问题,但这是另一个问题。 (具体参见 13.10.3.3 以函数模板的地址推导模板参数)。
  • @HolyBlackCat 本期的主题是找出能够有说服力地证明这个例子是错误的相关规定。如果该条款不存在或含糊不清,我们可以认为这是一个缺陷。

标签: c++ templates language-lawyer explicit-specialization


【解决方案1】:

您的模板定义不匹配,因为 void fun(T) 不是您的专业领域的 T fun(T),或者如果您有 int fun(T) 专攻 int fun(int),则可能相反。

您只需更改为:

template<class T>
T fun(T){}

template<>
int fun(int){}

顺便说一句:所有这些都会导致很多警告,因为您没有返回任何内容:-)

为什么不匹配:

template<class T>
void fun(T) {}

将 T=int 扩展为:

template<class T>
void fun(int) {}

但是:专业化(它不是一个,因为它不匹配)

template <>
int fun(int){return 0;}

有一个永远无法从原始模板定义推导出来的返回类型,因为它永远不是特化,因为它总是返回类型 void 而您的特化具有 int

【讨论】:

  • @xmh0511 您需要参考 c++ 文档 在哪里可以找到 void x()int x() 不同?真的吗?
  • @xmh0511:我相信你没有发现你的错字:-) 我希望在我的回答中更清楚一点。您的模板的定义根本无法扩展到您的专业化,唯一可行的情况是 void。但这不是你写的。如果您只是为模板中的每个 T 写一个 int,那么您的专业化程度就不同了。就是这样!
  • @Klaus 但是在标准(标签中的 [language-lawyer])中的哪个位置说模板函数特化必须具有与非特化版本相同的返回类型?跨度>
  • @RichardCritten:也许我的英语太差了。但同样:如果你写一个专业,给定的模板必须能够适应原始模板的形式。但是没有办法从给定的模板中创建特化,因为原始模板总是返回 VOID,特化返回 INT!那永远不匹配!如果您将返回类型也设置为模板参数,以便原始模板可以返回不同的类型,则它可以工作。但是你已经定义了无效并且只有无效。返回值不是“可变的”,因为它被写成固定的。
  • @Klaus 我知道,并且 OP 也知道 - OP 询问 C++ 标准([language-lawyer] 标签)中的哪个位置,即 OP 希望引用 C++ 标准作为一部分答案。
【解决方案2】:

您的报价是正确的。我们还考虑以下文本:

在所有这些情况下,P 是被视为潜在匹配的函数模板的类型,而 A 是...声明中的函数类型...推导按照 [temp.deduct.type ].

这些 P 和 A 类型是什么?来自[temp.deduct.type]

试图找到使 P 在替换推导值(称为推导 A)后与 A 兼容的模板参数值。

没有任何 T 值可以使 A = int fun(int)P = void fun(T) 兼容。

【讨论】:

  • 答案是合理的。我认为 [temp.expl.spec] 缺少对 [temp.deduct.decl] 的引用,除非 [temp.expl.spec] p10 提到了引用。 [temp.expl.spec] p10 不适用于template&lt;&gt; void fun&lt;int&gt;(int)。顺便说一句,[temp.deduct.type] p10 缺少用T 形式推断函数类型的返回类型的话语。
猜你喜欢
  • 1970-01-01
  • 2019-02-26
  • 2011-01-30
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 2015-02-22
相关资源
最近更新 更多