为什么VS2008在没有警告的情况下编译时使用了错误的模板逻辑

Why VS 2008 compile with no warning with an erroneous template logic?

本文关键字:错误 编译 VS2008 警告 为什么 情况下      更新时间:2023-10-16

我有一个简单的模板示例,如下所示:

template<class T> class A {
   friend int f(T);
}
int main(){
   A<int> a;
   return 0;
}

该代码在VS2008中编译和执行时没有发出警告(未使用的变量除外)。我认为这应该是一个问题,因为我们在同一个类中只获得了一个定义的非模板函数的许多版本。我错过什么了吗?

为什么此代码会产生错误?对于实例化A的每一个T,都会声明一个新函数并添加好友。永远不会有两个相同的函数,因为你不能为同一类型实例化一个模板两次(你只需要重用旧的实例化)。

此外,即使以某种方式可以生成两个相等的声明,也不会有歧义,因为函数首先在类中声明。因此,除了依赖于参数的查找之外,其他任何方法都无法找到它们。(基本上,这些函数是无用的,因为它们不能被调用)

§7.3.1.2 [namespace.memdef] p3

[…]如果非局部类中的friend声明首先声明了一个类或函数,则友类或函数是最内部封闭命名空间的成员在该命名空间范围中提供匹配声明之前(在授予友谊的类定义之前或之后),通过非限定查找或限定查找都找不到朋友的名称。[…]

另外,请参阅此。

根据C++标准,对未使用的模板函数进行语法检查的程度取决于实现。编译器不进行任何语义检查——例如,不查找符号。