C++ 按返回类型重载函数模板
我无意中发现以下两个模板可能会过载(不要引起名称重定义错误),我认为这是违反直觉的C++ 按返回类型重载函数模板,c++,templates,overloading,C++,Templates,Overloading,我无意中发现以下两个模板可能会过载(不要引起名称重定义错误),我认为这是违反直觉的 template<typename T> void func(T) {} template<typename T> int func(T) {return 0;} 模板 void func(T){} 模板 int func(T){返回0;} 在cppreference.com上,有一个相关段落: 当使用类型或非类型模板参数的表达式 出现在函数参数列表或返回类型中 表达式仍然是函数的函
template<typename T>
void func(T) {}
template<typename T>
int func(T) {return 0;}
模板
void func(T){}
模板
int func(T){返回0;}
在cppreference.com上,有一个相关段落:
当使用类型或非类型模板参数的表达式
出现在函数参数列表或返回类型中
表达式仍然是函数的函数模板签名的一部分
超载的目的:
但是这两个函数的返回类型不包括t
。谁能为我解释一下
以下两个模板可以重载(不要引起名称重定义错误),我认为这是违反直觉的
不是真的
这两个函数不能重载,但编译器直到实例化它们时才知道它们的存在:
// Try invoking `func`
func(0xFF);
现在,编译器将抛出类似以下内容的错误消息:
error: call to 'func' is ambiguous
你引用的段落无关紧要 有一条特殊规则可以防止只在返回类型上不同的非模板函数重载(来自标准[over.load]/2.1): 不能重载仅在返回类型、异常规范或两者中不同的函数声明 因此,如果存在这样的声明(即使程序不调用它们),那么程序的格式是错误的。但是,此规则既不适用于函数模板,也不适用于根据[over.load]/1为重载解析目的而合成的模板专门化 并非所有函数声明都可以重载。这里指定了那些不能重载的。如果程序在同一作用域中包含两个这样的不可重载声明,则该程序是格式错误的。[ 注意:此限制适用于作用域中的显式声明,以及此类声明和通过using声明进行的声明之间的显式声明。它不适用于由于名称查找(例如,由于使用指令)或重载解析(例如,对于运算符函数)而生成的函数集- 尾注 ] 因此,这两个模板可以很好地重载
然而,正如Dean Seo在他的回答中所说,如果您试图调用
func
,由于重载解析的模糊性,程序将是格式错误的。现在尝试实际调用func()
,而不会导致重载失败。模板实际上是宏定义;在展开模板之前,编译器无法检测到模板中的大多数错误。请尝试调用func。