【问题标题】:Inheritance and member-function templates overloading继承和成员函数模板重载
【发布时间】:2011-12-18 02:09:21
【问题描述】:

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

【问题讨论】:

  • 耐人​​寻味。没有工作的 clang 设置 a.t.m.但看起来它可能是一个错误。尽量避免__a 命名:以下划线开头的名称被标准保留
  • FWIW、MSVC10 和 GCC 4.4.5 编译也很好,而 Clang 3.1 也拒绝该代码。还有,肯定和using A::a;有关,把函数模板直接放到B里面就可以清除错误了。
  • @sehe 只是好奇,你有没有尝试编译我的代码?你用的是哪个编译器?
  • @mattia.penati:只有 g++ 4.4 到 g++-4.6.1 快速(有和没有 -std=c++0x)
  • g++ 似乎在做正确的事。我很好奇您是否尝试将函数a()A 直接移动到B,而不是using 呢?或者说是继承+使用的问题,还是简单的名字解析问题?

标签: c++ templates inheritance overloading


【解决方案1】:

深入研究 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 不合规。

【讨论】:

  • 对于成员函数模板,参数类型列表如何确定?我的意思是,模板参数推导发生了吗?
猜你喜欢
  • 2014-11-11
  • 1970-01-01
  • 2023-01-15
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 2012-10-26
相关资源
最近更新 更多