C++ 请求加入成员“…'”;在g+中是不明确的+;

C++ 请求加入成员“…'”;在g+中是不明确的+;,c++,gcc,g++,ambiguous,C++,Gcc,G++,Ambiguous,在我的一个类中,使用gcc 3.4.5(mingw),我遇到了以下编译错误: 其中,m_model是指向IRigidBody对象的指针,IRigidBody仅从IListener继承,而不是从IListener 作为合理性检查,我使用doxygen生成类层次结构图,doxygen同意我的观点,即IRigidBody不是从IListener 显然,我对C++中的继承性的理解并不完全正确。我的印象是,IListener和IListener是两种不同的类型,函数声明 addListener(IList

在我的一个类中,使用gcc 3.4.5(mingw),我遇到了以下编译错误:

其中,
m_model
是指向
IRigidBody
对象的指针,
IRigidBody
仅从
IListener
继承,而不是从
IListener

作为合理性检查,我使用doxygen生成类层次结构图,doxygen同意我的观点,即
IRigidBody
不是从
IListener

显然,我对C++中的继承性的理解并不完全正确。我的印象是,
IListener
IListener
是两种不同的类型,函数声明

addListener(IListener<const SConsolePacket&>* listener)
但还是会犯这样的错误。我一辈子都看不出这些函数是多么的模棱两可。有人能解释这个问题吗

另外,我知道如何通过这样做强制函数不含糊:

m_controller->ISource<const SControlPacket&>::addListener( m_model );
m_控制器->ISource::addListener(m_模型);
我只是碰巧认为这是非常不可吃的,我宁愿不这样做

编辑。。。只是开玩笑。这显然不能解决问题,因为它会导致链接器错误:

CModelTesterGui.cpp:1312: undefined reference to `utility::ISource<aerobat::SControlPacket const&>::addListener(utility::IListener<SControlPacket const&>*)'
CModelTesterGui.cpp:1312:utility::isosource::addListener(utility::IListener*)的未定义引用

看起来您的情况是这样的:

m_controller->addListener(
        static_cast<IListener<const SControlPacket&>*>(m_model) );
struct A {
  void f();
};

struct B {
  void f(int);
};

struct C : A, B { };

int main() { 
  C c; 
  c.B::f(1); // not ambiguous
  c.f(1);    // ambiguous
}
对f的第二个调用是不明确的,因为在查找名称时,它会在两个不同的基类作用域中找到函数。在这种情况下,查找是不明确的——它们不会使彼此过载。修复方法是对每个成员名称使用using声明。查找将在
C
范围内查找名称,不进一步查找:

struct C : A, B { using A::f; using B::f; };
现在,调用将找到两个函数,执行重载解析,并发现取
int
的函数将适合。在代码中,这意味着您必须执行以下操作

struct controller : ISource<const SConsolePacket&>, ISource<const SControlPacket&> {
  using ISource<const SConsolePacket&>::addListener;
  using ISource<const SControlPacket&>::addListener;
};
结构控制器:ISource,ISource{ 使用ISource::addListener; 使用ISource::addListener; };
现在,这两个名称在同一范围内,现在它们可以互相重载。查找现在将停止在控制器类,而不是深入到两个基类分支

SControlPacket和SConsolePacket之间的关系是什么?请添加为什么最后一行
m\u controller->isoource::addListener(m\u模型)消除呼叫的歧义?如果函数重载,它们应该在同一个类中。这些函数在哪里声明?@GRB没有关系。两者都是从无到有的结构@利特:我错了。它使它可以编译,但当链接器试图查找纯虚拟的ISource::addListener(…)时,结果会导致链接错误。现在我很困惑。当你说“声明”时,我想你的意思是“定义”。它们是在从IController派生的concrete类中定义的。@cheshirekow,我的意思是声明的,未定义的。执行“a.B::f”会禁用虚拟调用机制。然后,如果这样调用纯虚函数,则必须存在纯虚函数的定义。对于名称查找,仅声明很重要。在这种情况下,using声明可以阻止这些歧义。@litb,明白了。你说得对。谢谢你的回答!美好的这就是这些东西的用途。我认为我从来没有真正理解过使用声明(这是不真正理解名称查找的结果)。非常感谢你。作为说明,我实际上将using声明放在了IController接口中。我认为这是一个合适的地方。至少在g++中,不允许两次使用。您可以在派生类C中选择A::f或B::f。@Dingle首先是g++-fwiw的旧版本(对于最近的用户),4.7.2处理了两种用法,非常好,有点澄清,在多变量继承的情况下,我应该怎么做?那么,为什么标准要求编译器举起手臂,而不是在原始情况下进行重载解析呢?
struct A {
  void f();
};

struct B {
  void f(int);
};

struct C : A, B { };

int main() { 
  C c; 
  c.B::f(1); // not ambiguous
  c.f(1);    // ambiguous
}
struct C : A, B { using A::f; using B::f; };
struct controller : ISource<const SConsolePacket&>, ISource<const SControlPacket&> {
  using ISource<const SConsolePacket&>::addListener;
  using ISource<const SControlPacket&>::addListener;
};