【问题标题】:Name conflict between member function and class name成员函数与类名冲突
【发布时间】:2015-02-26 08:06:28
【问题描述】:

我正在用 wxWidgets 编写一个国际象棋程序。有一次,我有一个wxGLCanvas 的子类,它使用了我编写的Move 类。不幸的是,似乎有一个方法wxWindowBase::Move(),所以我所有list<Move> li 形式的语句都无法编译。

有什么好办法解决这个问题吗?我试过list< ::Move> li,这确实解决了问题,但它很严重,我必须在任何地方进行更改。与命名空间冲突不同,使用声明在这里似乎没有帮助。

【问题讨论】:

  • 你尝试过什么using 声明(或等效的typedef)?

标签: c++ name-clash name-conflict name-collision


【解决方案1】:

有几种方法可以消除被方法名称隐藏的基类的歧义。

typedef Move::Move Move_Base; // 1. the LHS of :: operator ignores functions
using typename Move::Move; // 2. non-template "typename" avoids constructor
typedef class Move Move_Base; // 3. elaborated type specifier
typedef ::Move Move_Base; // 4. namespace qualification (as mentioned)

(1) 可能由于错误而无法在 GCC 中工作。 (不确定;你可以试试看。)

(2) 可能是最优雅的,但编译器必须正确处理 C++11 的一些细微差别。 typename 关键字在 C++03 中是非法的,但我认为没有必要。在 C++11 中,语法指的是构造函数而不是类型名称,除非你说 typename

您需要将继承的函数限定为wxWindowBase::Move()

(3) 仅在基类是当前命名空间的一部分时才有效,而这通常不应该是。

(4) 有点痛苦,因为如果将一个类硬编码到其封闭的命名空间中,则需要对其进行修改。正如你所说,有点丑。

【讨论】:

  • No permutation of 2) 似乎有效,但不知何故我忘记了 typedefs,它或多或少地解决了我的问题。谢谢!
  • @HenrySwanson 嗯,GCC 接受声明,但 Clang 不接受,这看起来像一个错误。但是,GCC 仍然 doesn't 将这样的声明解释为解决歧义,这是另一个错误。
【解决方案2】:

将您的代码放入命名空间。那么你的班级将是something::Move,它不会那么容易发生冲突。

【讨论】:

  • 这似乎是同样的问题;这只是它所在的命名空间的区别。我喜欢能够在我的 .cpp 文件中包含 using something::Move,所以像 std::list<something::Move> 这样的东西变成了 list<Move>,IMO 更具可读性。
  • 我不明白:如果你的代码在namespace something,那么你可以说list<Move>而不是using
  • 可以,但还是把Move类误认为Move方法。
  • @HenrySwanson:也许你应该重命名你的班级并避开这个烂摊子。
  • 我可以,但是我还能称一个存储“这就是这件作品的去处以及它是否被捕获”的类呢?我只是希望有某种方法可以使它变得漂亮;我可以忍受额外的::
猜你喜欢
  • 2019-11-23
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 2010-11-26
  • 2014-04-30
  • 2016-05-03
  • 2013-10-24
相关资源
最近更新 更多