我遇到了一个奇怪的问题,我想知道为什么g ++ 4.1.2的表现方式就像它一样。
剥离其基本要素:
#include <iostream>
template<typename T>
inline void f(T x) { std::cout << x*x; }
namespace foo {
class A {
public:
void f() const { f(2); }
};
}
对f(2)
的调用失败,因为编译器无法匹配模板函数f
。
我可以使用::f(2)
,但我想知道为什么这是必要的,因为它是完全明确的,并且就我的(公认的过时)匹配规则的知识而言,这应该有用。 / p>
答案 0 :(得分:12)
编译器从当前范围开始检查候选的所有范围。它在直接范围内找到名为f
的函数,并停止搜索。您的模板版本永远不会被视为候选人。
有关完整说明,请参阅Namespaces and the Interface Principle。
答案 1 :(得分:5)
参见C ++ 03部分
3.4.1非限定名称查找
在3.4.1中列出的所有情况下,在每个相应类别中列出的顺序中搜索范围;一旦找到名称的声明,名称查找就会结束。如果没有找到声明,该程序就会形成错误。
在您的代码示例中,编译器在当前作用域中找到名称f
,从而结束非限定名称查找,但函数原型中存在不匹配,因此您收到错误。
使用::
对其进行限定使其有效,因为然后在全局命名空间中搜索该名称,并调用具有正确原型的f
。
答案 2 :(得分:2)
似乎编译器试图调用A :: f并因为参数而失败,这在某种程度上似乎是正常的。如果使用非模板函数,是否会出现相同的错误?