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

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

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

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

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

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

4

2 回答 2

6

您的模板定义不匹配,因为您的专业化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.

于 2021-12-22T11:44:40.733 回答
5

你的报价是正确的。让我们也考虑以下文本:

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

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

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

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

于 2021-12-22T20:45:30.557 回答