是否有规定在函数模板显式专业化中指定对“返回类型”的限制?

jac*_*k X 18 c++ templates language-lawyer explicit-specialization

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

template<>
int fun(int){return 0;}
Run Code Online (Sandbox Code Playgroud)

考虑这个例子,它被所有实现拒绝。但是,我在当前标准中没有发现任何有说服力的条款来指定这种显式专业化声明的格式不正确。如果存在的话,规则是什么?

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

如果对于如此考虑的一组函数模板,在考虑部分排序后没有匹配或有多个匹配([temp.func.order]),则推导失败,并且在声明情况下,程序有问题-形成。

我认为“匹配”的含义在这里还不够明确,因为“匹配”没有明确定义任何内容。

Kla*_*aus 6

您的模板定义不匹配,因为void fun(T)它不属于T fun(T)您的专业领域,或者如果您必须int fun(T)专门从事int fun(int).

您只需更改为:

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

template<>
int fun(int){}
Run Code Online (Sandbox Code Playgroud)

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

为什么不匹配:

template<class T>
void fun(T) {}
Run Code Online (Sandbox Code Playgroud)

将 T=int 展开为:

template<class T>
void fun(int) {}
Run Code Online (Sandbox Code Playgroud)

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

template <>
int fun(int){return 0;}
Run Code Online (Sandbox Code Playgroud)

具有永远无法从原始模板定义中推导出来的返回类型,因为它永远不是专业化,因为它始终具有返回类型,void而您的专业化具有int.

  • @Klaus但是标准中的哪个位置(标签中的[语言律师])是否说模板函数专业化必须具有与非专业化版本相同的返回类型? (2认同)
  • @Klaus我知道这一点,并且OP知道 - OP正在询问C ++标准([语言律师]标签)中的哪里,它说,即OP希望引用C ++标准作为答案的一部分。 (2认同)

MSa*_*ers 5

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

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

P 型和 A 型分别是什么?来自 [temp.deduct.type]

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

只是没有 T 的值可以A = int fun(int)P = void fun(T).