【问题标题】:template function matching in g++g ++中的模板函数匹配
【发布时间】:2011-05-07 07:48:19
【问题描述】:

我遇到了一个奇怪的问题,我想知道为什么 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) 一起工作,但我想知道为什么这是必要的,因为它是完全明确的,而且就我(诚然过时的)匹配规则知识而言,这应该有效。

【问题讨论】:

  • 你用的是什么版本的g++?
  • @j_random_hacker:这有关系吗?这种行为不是严格按照标准吗?
  • @Konrad:我不知道,但我不会假设!当然,两个 f() 都在调用范围内;由于foo::A::f() 的参数数量错误,应该将其从“可行”函数集中删除...?
  • @j_random_hacker:不,他们不是,不仅有命名空间,还有类范围本身。
  • 无需限定每次使用的简单解决方法是在函数体中添加using ::f。这将把全局命名空间f 带入函数的范围,在那里它将与foo::A::f 一起成为候选对象

标签: c++ templates g++ matching


【解决方案1】:

编译器检查候选的所有范围,从当前范围开始。它在直接作用域中找到一个名为 f 的函数,然后停止搜索。您的模板版本永远不会被视为候选版本。

完整说明请参见Namespaces and the Interface Principle

【讨论】:

  • +1 和很棒的链接。 Sutter's Mill 的所有文章都很棒。
【解决方案2】:

参考C++03部分

3.4.1 非限定名称查找

在 3.4.1 中列出的所有情况下,按照每个相应类别中列出的顺序搜索范围以查找声明; 一旦找到名称的声明,名称查找就会结束。如果没有找到声明,则程序格式错误。

在您的代码示例中,编译器在当前范围内找到名称 f,从而结束非限定名称查找,但函数原型不匹配,因此您会收到错误。

使用:: 对其进行限定使其工作,因为然后在全局命名空间中搜索名称并调用具有正确原型的f

【讨论】:

  • 另一种可能性,将名称显式纳入范围using ::f; f(2);
【解决方案3】:

编译器似乎试图调用 A::f 并因为参数而失败,这在某种程度上似乎很正常。如果使用非模板函数,是否也会出现同样的错误?

【讨论】:

  • 原来命名空间和模板是红鲱鱼。 #include void f(int x) { std::cout
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 2013-04-11
相关资源
最近更新 更多