che*_*kow 10 c++ gcc g++ ambiguous
我在我的一个类中使用gcc 3.4.5(mingw)得到以下编译错误:
src/ModelTester/CModelTesterGui.cpp:1308: error: request for member `addListener' is ambiguous
include/utility/ISource.h:26: error: candidates are: void utility::ISource<T>::addListener(utility::IListener<T>*) [with T = const SConsolePacket&]
include/utility/ISource.h:26: error: void utility::ISource<T>::addListener(utility::IListener<T>*) [with T = const SControlPacket&]
Run Code Online (Sandbox Code Playgroud)
希望你能看到这ISource<T>是一个模板接口,它只是表明该对象可以是某个匹配类型的对象的informer IListener<T>.让我烦恼的是这个想法,由于某种原因,功能是模棱两可的,据我所知,它们不是.addListener()对于不同的输入类型IListener<const SConsolePacket&>,该方法会被重载IListener<const SControlPacket&>.用法是:
m_controller->addListener( m_model );
Run Code Online (Sandbox Code Playgroud)
m_model指向IRigidBody对象的指针在哪里,并且IRigidBody仅从,IListener< const SControlPacket& >并且绝对不是从IListener< const SConsolePacket& >
作为一个完整性检查,我使用doxygen来生成类层次结构图,并且doxygen同意我的IRigidBody不同意IListener< const SConsolePacket& >
显然,我对c ++中的继承性的理解并不完全正确.我的印象是IListener<const SControlPacket&>,它IListener<const SConsolePacket&>是两种不同的类型,而且是函数声明
addListener(IListener<const SConsolePacket&>* listener)
Run Code Online (Sandbox Code Playgroud)
和
addListener(IListener<const SControlPacket&>* listener)
Run Code Online (Sandbox Code Playgroud)
声明两个单独的函数,它们根据输入参数的(不同的)不同类型执行两个单独的操作.此外,我的印象是指向IRigidBodya的指针也是指向a的指针,IListener<const SControlPacket&>并且通过调用addListener( m_model )编译器应该理解我正在调用上述两个函数中的第二个.
我甚至试过m_model像这样的铸造:
m_controller->addListener(
static_cast<IListener<const SControlPacket&>*>(m_model) );
Run Code Online (Sandbox Code Playgroud)
但仍然得到那个错误.我不能为我的生活看到这些功能是如何模棱两可的.任何人都可以解释这个问题吗?
PS我知道如何通过这样做强制该功能不明确:
m_controller->ISource<const SControlPacket&>::addListener( m_model );
Run Code Online (Sandbox Code Playgroud)
我碰巧认为这是非常不可读的,我宁愿不必这样做.
编辑......开个玩笑.这显然无法解决问题,因为它会导致链接器错误:
CModelTesterGui.cpp:1312: undefined reference to `utility::ISource<aerobat::SControlPacket const&>::addListener(utility::IListener<SControlPacket const&>*)'
Run Code Online (Sandbox Code Playgroud)
Joh*_*itb 24
看起来你的情况是这样的:
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
}
Run Code Online (Sandbox Code Playgroud)
对f的第二次调用是不明确的,因为在查找名称时,它会在两个不同的基类范围中查找函数.在这种情况下,查找是不明确的 - 它们不会相互过载.修复方法是为每个成员名称使用using声明.查找将在范围内查找名称,C不进一步查找:
struct C : A, B { using A::f; using B::f; };
Run Code Online (Sandbox Code Playgroud)
现在,调用将找到两个函数,执行重载解析,并发现一个函数int适合.继承您的代码,这意味着您必须执行以下操作
struct controller : ISource<const SConsolePacket&>, ISource<const SControlPacket&> {
using ISource<const SConsolePacket&>::addListener;
using ISource<const SControlPacket&>::addListener;
};
Run Code Online (Sandbox Code Playgroud)
现在,这两个名称在同一范围内,现在它们可以相互重载.Lookup现在将停在控制器类,而不是进一步深入两个基类分支.
| 归档时间: |
|
| 查看次数: |
14117 次 |
| 最近记录: |