继承和成员函数模板重载

Inheritance and member-function templates overloading

本文关键字:重载 函数模板 成员 继承      更新时间:2023-10-16

我尝试用clang(3.0版本)编译以下代码,但它给了我这个错误

error: no matching member function for call to 'a'

在呼叫__a.a<0>()。然后我尝试使用g++(版本4.2.1),它按预期编译和工作(打印出1 2)。

#include <iostream>
struct A {
  template <int> int a() { return 1; }
};
struct B: A {
  using A::a;
  template <int,int> int a() { return 2; }
};
int main(int, char **) {
  B __a;
  std::cout << __a.a<0>() << " "  << __a.a<0,0>() << std::endl;
  return 0;
}

我试着去看标准,但我没有发现任何解释编译器正确行为的东西。现在,我的问题是,哪个是正确的行为,如果clang工作正常,我如何修改我的代码工作预期?

深入研究c++ 03和c++ 11标准,您的代码有效且格式良好看起来并不好。c++ 03似乎允许这样做,而c++ 11标准的措辞变化似乎不允许这样做。

§7.3.3 [namespace.udecl] (Both standards)

using声明将基类中的名称引入派生类作用域时,派生类中的成员函数覆盖和/或隐藏基类中具有相同名称和参数类型的成员函数(而不是冲突)。

注意,这里没有提到任何成员函数模板。

p15 (c++ 11)当using-declaration将基类中的名称引入派生类作用域时,派生类中的成员函数和成员函数模板覆盖和/或隐藏基类中具有相同名称的成员函数和成员函数模板、形参类型列表(8.3.5)、csv -qualification和ref-qualifier(如果有的话)(而不是冲突)。

注意在新的措辞中提到了成员函数模板。还要注意,确定派生类成员是否覆盖/隐藏基类成员的列表没有提到成员函数模板的模板参数列表作为标识点,因此它被忽略。

我可能完全解释错了,但似乎Clang在这里是符合标准的编译器,而GCC以及MSVC10根据新的措辞是不符合标准的。