按返回类型重载函数模板

Overload function template by return type

本文关键字:函数模板 重载 返回类型      更新时间:2023-10-16

我不小心发现以下两个模板可能会过载(不要引起名称重新定义错误),我认为这是违反直觉的。

template<typename T>
void func(T) {}
template<typename T>
int func(T) {return 0;}

从 cppreference.com,有一个相关的段落:

当表达式使用类型或非类型模板参数时 出现在函数参数列表或返回类型中, 表达式仍然是函数模板签名的一部分 重载目的:

但是这两个函数的返回类型不包括T。谁能为我解释?

你引用的段落无关紧要。

有一个特殊的规则可以防止仅在返回类型上不同的非模板函数被重载(来自标准 [over.load]/2.1):

仅在返回类型、异常规范或两者上不同的函数声明不能重载。

因此,如果存在此类声明,则程序格式不正确(即使程序不调用它们)。但是,此规则既不适用于函数模板,也不适用于根据 [over.load]/1 为重载解析而合成的模板专用化。

并非所有函数声明都可以重载。此处指定了不能重载的那些。如果程序在同一范围内包含两个此类不可重载声明,则程序格式不正确。[ 注意:此限制适用于作用域中的显式声明,以及此类声明与通过 using 声明进行的声明之间的显式声明。它不适用于由于名称查找(例如,由于 using-指令)或重载解析(例如,对于运算符函数)而制造的函数集。— 尾注 ]

因此,这两个模板可以很好地重载。

然而,正如Dean Seo在他的回答中所说,如果你试图调用func,由于过载分辨率的模糊性,程序将格式不正确。

以下两个模板可能会重载(不要引起名称重新定义错误),我认为这是违反直觉的。

没有。

这两个函数不能重载,但编译器直到它们被实例化的那一刻才知道它们的存在:

// Try invoking `func`
func(0xFF);

现在编译器将抛出类似于以下内容的错误消息:

error: call to 'func' is ambiguous