同一函数的模板化和非模板化版本是否被视为重载?

Is a templated and a nontemplated version of the same function considered an overload?

一个非常正式的问题:这是否被认为是过载?删除模板与仅重载参数有根本不同吗?

template<class T> void myFunction(const T& t) {}
void myFunction(const double& t) {}

那么接下来的问题是,采用这种方法还是使用模板特化而不是重载更好?

template<> void myFunction(const double& t) {}

首先,根据标准(§13 的开头):“当两个 一个或多个不同的声明在 相同的范围,据说该名称已重载。[...]仅功能和 函数模板声明可以重载;变量和类型 声明不能超载。”很明显,你的两个 声明是重载。

如果您调用myFunction( 3.14159 ),那么模板将是 使用与非模板相同的签名实例化,两者都将 是精确匹配。在这种情况下 (§13.3.1):

Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then [...] — F1 is a non-template function and F2 is a function template specialization, [...]

标准已指定您的具体情况。

关于专门化函数的替代方案: 根据上面的定义,专业化可能是重载,但是 他们不参与过载决议。专业工作 不同的是:没有它们首先发生重载决议;那么,如果 重载决议选择了模板,并且有一个 实例化类型的特化,特化是 使用,而不是模板的通用实例化。一般来说 说起来,结果是一样的,虽然 http://www.gotw.ca/publications/mill17.htm 指出一种异国情调(和 写得不好?)他们不是的情况。尽管如此,至少对我来说,似乎 更自然地提供重载功能,而不是 模板专业化。无论如何,大多数时候。 (有一个真实的 例外:有时不提供泛型是有用的 实施,但只是专业化。根据我的经验,这 情况通常发生在特征 类 上,但也可能发生在 个人功能也是如此。在这种情况下,你当然可以 专门化模板;否则你不能使用它。)