不需要"模板"关键字?[gcc/clang/Comeau bug?]

Pra*_*rav 10 c++ templates g++

这是测试代码

template <class T> void f()
{
  T t;
  t.f<T>(0); //compiles even without the "template" keyword, what am I missing?
}

class abc
{
  public:
  template <typename T>
  void f (int){}
};

int main()
{
  f<abc>();
}
Run Code Online (Sandbox Code Playgroud)

我正在使用g ++ 4.4.6.谢谢

PS:我已经大大改编了我的问题.请不要介意.

编辑 :我向EDG人员提出这个问题,这就是Mike Herrick所说的

我们确实将此诊断为--strict模式中的错误以及启用从属名称查找的任何模式(例如, - define_name, - batch_templates).在GNU仿真模式中禁用从属名称查找,因此在这种情况下我们不会发出此错误.

从属名称处理要求启用非类原型实例化(见下文).与非类原型实例一样,在编译未编写该功能的代码时,启用依赖名称查找可能会导致编译错误.

依赖名称查找规则要求在模板定义中的使用点查找非依赖名称,并且在该点处对非依赖调用执行重载决策.对于依赖调用,所考虑的名称集是在模板定义中的使用点处可见的集合,以及在实例化时通过依赖于参数的查找可见的任何名称.请注意,内置类型没有关联的命名空间,因此仅具有内置类型的调用只能解析为模板定义中可见的名称.此外,非限定查找不会看到依赖基类的名称.

以下说明了使用从属名称查找时遇到的一些最常见的代码问题:

template <class T> struct B {
    void f();
  };

template <class T> struct A : public B<T> {
    X x;  // error: X not visible yet (formerly an error in strict mode)
    void g() {
      f();        // error: B<T>::f not visible
      this->f();  // must be written this way
      h(1);  // error: h(int) not visible using argument-dependent lookup
    }
  };
struct X {};
void h(int);
A<int> ai;
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 8

template关键字必需的,因为它t是一个从属名称,因为它f<T>是一个依赖成员函数模板特化.相关规范分散在第14节中,但从§14.2/ 4开始(在C++ 03和C++ 11中).

问题是由于名称查找不正确:gcc f在声明点找到命名空间范围函数模板,然后在实例化时解析f为成员函数模板abc.

如果重命名命名空间范围函数模板或成员函数模板,您将从编译器获得正确的行为.

这是一个长期存在的gcc bug:

错误接受缺少"template"关键字的代码

在不同范围内具有相同名称的奇怪冲突

另请参阅针对这两者解决的许多重复错误.我没有看到一个Clang错误.

在C++ 03中,未详细说明函数模板中的名称查找; 有关该主题的报道存在许多缺陷,并且规范在C++ 11中经历了重大变化,以澄清细节和极端情况以及修复细微问题.