什么是有效的函数模板重载

函数模板可以在非模板函数重载规则下重载(相同名称,但参数类型不同),除此之外,如果重载,则重载是有效的

  • 返回类型不同,或
  • 模板参数列表不同,除了参数的命名和默认参数的存在(它们不是签名的一部分)

对于普通函数,比较两种参数类型对于编译器来说很容易,因为它具有所有信息。但是模板中的类型可能尚未确定。因此,两个参数类型相等的规则在这里是近似的,并且表示非依赖性类型和值需要匹配,并且依赖类型和表达式的拼写需要相同(更准确地说,它们需要符合所谓的 ODR 规则,除了可以重命名模板参数。但是,如果在这种不同的拼写下,类型中的两个值被认为是不同的,但总是实例化为相同的值,则重载无效,但编译器不需要诊断。

template<typename T>
void f(T*) { }

template<typename T>
void f(T) { }

这是一个有效的重载,因为 T 和“T *”是不同的拼写。但以下情况无效,无需诊断

template<typename T>
void f(T (*x)[sizeof(T) + sizeof(T)]) { }

template<typename T>
void f(T (*x)[2 * sizeof(T)]) { }