继承和成员函数模板重载

时间:2011-12-18 02:09:21

标签: c++ templates inheritance overloading

我尝试使用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正常工作,我如何修改我的代码以按预期工作?

1 个答案:

答案 0 :(得分:2)

通过C ++ 03和C ++ 11标准,您的代码有效且格式良好并不合适。 C ++ 03似乎允许这样做,而C ++ 11标准的措辞的改变似乎不允许这样做。

§7.3.3 [namespace.udecl] (Both standards)

  

p12(C ++ 03)当 using-declaration 将基类中的名称带入派生类范围时,派生类中的成员函数会覆盖和/或隐藏具有相同功能的成员函数基类中的名称和参数类型(而不是冲突)。

请注意,此措辞未提及任何成员函数模板。

  

p15(C ++ 11)当 using-declaration 将基类中的名称带入派生类范围时,派生类中的成员函数和成员函数模板会覆盖和/或隐藏成员函数和成员函数模板在基类中具有相同的名称,参数类型列表(8.3.5),cv-qualification和 ref-qualifier (如果有)(而不是冲突)。

请注意新措辞中提到的成员函数模板。另请注意,确定派生类成员是否覆盖/隐藏基类成员的列表未提及成员函数模板的 template-parameter-list 作为标识点,它正在为此目的而忽略了。

我可能完全错误地解释了这一点,但看来Clang在这里是符合标准的编译器,GCC以及MSVC10根据新的措辞是不符合的。