请求会员“...”在 g++ 中是不明确的
我使用 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&]
希望您可以看到 ISource
是一个模板接口,仅指示该对象可以是某种匹配类型 IListener
的对象的通知者。因此,让我感到恼火的是这样的想法:由于某种原因,函数是不明确的,而据我所知,它们并非如此。 addListener()
方法针对不同的输入类型 IListener
和 IListener
进行重载。用法是:
m_controller->addListener( m_model );
其中m_model
是指向IRigidBody
对象的指针,而IRigidBody
仅继承自IListener
并且绝对不是来自 IRigidBody
。 const SControlPacket& >IListener< const SConsolePacket& >
作为健全性检查,我使用 doxygen 生成类层次结构图,并且 doxygen 同意我的观点,即 IRigidBody
不是从 IListener
派生的。 const SConsolePacket& >
显然我对c++继承的理解并不完全正确。我的印象是 IListener
和 IListener
是两种不同的类型,并且函数声明
addListener(IListener<const SConsolePacket&>* listener)
和
addListener(IListener<const SControlPacket&>* listener)
声明两个单独的类型根据输入参数的(不同)不同类型执行两个单独的操作的函数。此外,我的印象是,指向 IRigidBody 的指针也是指向 IListener
我什至尝试像这样转换 m_model
:
m_controller->addListener(
static_cast<IListener<const SControlPacket&>*>(m_model) );
但仍然收到该错误。我一辈子都看不出这些功能有多么含糊。谁能阐明这个问题?
PS 我知道如何通过这样做来强制函数明确:
m_controller->ISource<const SControlPacket&>::addListener( m_model );
我只是碰巧认为这是非常不可读的,我宁愿不必这样做。
编辑……开个玩笑。这显然不能解决问题,因为它会导致链接器错误:
CModelTesterGui.cpp:1312: undefined reference to `utility::ISource<aerobat::SControlPacket const&>::addListener(utility::IListener<SControlPacket const&>*)'
I'm getting the following compile error in one of my classes, using 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&]
Hopefully you can see that ISource<T>
is a template interface that just indicates that the object can be an informer for an object that is of some matching type IListener<T>
. So the thing that has me irked is this idea that for some reason functions are ambiguous when, as far as I can tell, they are not. The addListener()
method is overloaded for different input types IListener<const SConsolePacket&>
and IListener<const SControlPacket&>
. The usage is:
m_controller->addListener( m_model );
Where m_model
is a pointer to an IRigidBody
object, and IRigidBody
inherits only from IListener< const SControlPacket& >
and definately not from IListener< const SConsolePacket& >
As a sanity check, I used doxygen to generate the class hierarchy diagram and doxygen agrees with me that IRigidBody
does not derive from IListener< const SConsolePacket& >
Evidently my understanding of inheritence in c++ is not exactly correct. I'm under the impression that IListener<const SControlPacket&>
and IListener<const SConsolePacket&>
are two different types, and that the function declarations
addListener(IListener<const SConsolePacket&>* listener)
and
addListener(IListener<const SControlPacket&>* listener)
declare two separate functions that do two separate things depending on the (distinct) different type of the parameter that is input. Furthermore, I'm under the impression that a pointer to an IRigidBody
is also a pointer to an IListener<const SControlPacket&>
and that by calling addListener( m_model )
the compiler should understand that I'm calling the second of the above two functions.
I even tried casting m_model
like this:
m_controller->addListener(
static_cast<IListener<const SControlPacket&>*>(m_model) );
but still get that error. I cannot for the life of me see how these functions are ambiguous. Can anyone shed light on this issue?
P.S. I know how to force the function to be un-ambiguous by doing this:
m_controller->ISource<const SControlPacket&>::addListener( m_model );
I just happen to think that is terribly unreadible and I would prefer not to have to do that.
Edit... just kidding. That apparently doesn't fix the problem as it leads to a linker error:
CModelTesterGui.cpp:1312: undefined reference to `utility::ISource<aerobat::SControlPacket const&>::addListener(utility::IListener<SControlPacket const&>*)'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来你的情况是这样的:
对 f 的第二次调用不明确,因为在查找名称时,它找到了两个不同基类作用域中的函数。在这种情况下,查找是不明确的 - 它们不会互相重载。解决方法是对每个成员名称使用 using 声明。查找将在
C
范围内查找名称,并且不再进一步查找:现在,调用将查找两个函数,进行重载解析,并发现采用
int
的函数会适合的。延续到您的代码中,这意味着您必须执行类似以下操作现在,这两个名称位于同一范围内,现在它们可以互相重载。查找现在将停止在控制器类,而不是进一步深入到两个基类分支。
Looks like your situation is like this:
The second call to f is ambiguous, because in looking up the name, it finds functions in two different base class scopes. In this situation, the lookup is ambiguous - they don't overload each other. A fix would be to use a using declaration for each member name. Lookup will find names in the scope of
C
and don't lookup further:Now, the call would find two functions, do overload resolution, and find that the one taking
int
will fit. Carried over to your code, it would mean that you have to do something like the followingNow, the two names are in the same scope, and now they can overload each other. Lookup will now stop at the controller class, not diving further into the two base-class branches.