假设我们有一个程序定义了几个函数模板:
template<typename T>
void g(T) {}
struct A {};
//this template only sees the definition of g above
//the usage of g does not depend on the parameter of the template
template<typename T = void>
decltype(T(), (g)(A{})) f(A a)
{
return (g)(a);
}
A g (A a)
{
return a;
}
//this template sees both overloads of g
//and still the usage of g does not depend on the parameter of the template
template<typename T = void>
decltype(T(), (g)(A{})) f(A a)
{
return (g)(a);
}
此程序包含两个定义功能模板 f 的代码副本。通常,C ++标准禁止创建等效的重载 问题是这两个模板是否符合标准?
如果这两个模板使用 g 作为依赖名称,那么它们将被视为等效,正如标准明确指出的那样:
为了确定两个相关名称([temp.dep])是否相等,只考虑名称本身,而不是模板上下文中的名称查找结果。如果同一函数模板的多个声明在此名称查找的结果中不同,则使用第一个声明的结果。
但是这里 g 的用法并不依赖于T(而是依赖于T的表达式的一部分)。
编译器不同意这两个定义是否应该被允许:clang接受它,GCC和Visual C ++不接受(见https://godbolt.org/g/LUW1iM)。