C++重载解析问题
我有以下结构:
struct A
{
A();
virtual ~A();
virtual void Foo() =0;
};
struct E;
struct F;
struct B: public A
{
B();
virtual ~B();
virtual void Bar(E*) =0;
virtual void Bar(F*) =0;
};
struct C: public B
{
C();
virtual ~C();
void Bar(E*);
};
struct D: public C
{
D();
virtual ~D();
void Foo();
void Bar(F*);
};
struct E: public A
{
E();
virtual ~E();
void Foo();
/* ... */
};
struct F: public A
{
F();
virtual ~F();
void Foo();
/* ... */
};
template <class _Base>
struct G: public _Base
{
G(const _Base &b)
: _Base(b)
{}
virtual ~G()
{}
using _Base::Bar; // doesn't help
/* ... */
};
当我尝试对 G
错误:没有匹配的函数可用于调用“G
::Bar(E*&)” 注意:候选者是:virtual void D::Bar(F*)
如果我重命名 (virtual) void Bar( 的声明F*),代码编译良好并按预期工作。
用法:
typedef std::list<E*> EList;
typedef std::list<F*> FList;
EList es;
FList fs;
G<D> player(D());
es.push_back(new E); // times many
fs.push_back(new F); // times many
for(EList::iterator i0(es.begin()), i1(es.end()); i0 != i1; ++i0)
{
player.Bar(*i0);
}
for(FList::iterator i0(fs.begin()), i1(fs.end()); i0 != i1; ++i0)
{
player.Bar(*i0);
}
1、使用不同参数的成员函数的多个重载有什么问题?
2、为什么编译器无法区分它们之间的区别?
I've got the following structure:
struct A
{
A();
virtual ~A();
virtual void Foo() =0;
};
struct E;
struct F;
struct B: public A
{
B();
virtual ~B();
virtual void Bar(E*) =0;
virtual void Bar(F*) =0;
};
struct C: public B
{
C();
virtual ~C();
void Bar(E*);
};
struct D: public C
{
D();
virtual ~D();
void Foo();
void Bar(F*);
};
struct E: public A
{
E();
virtual ~E();
void Foo();
/* ... */
};
struct F: public A
{
F();
virtual ~F();
void Foo();
/* ... */
};
template <class _Base>
struct G: public _Base
{
G(const _Base &b)
: _Base(b)
{}
virtual ~G()
{}
using _Base::Bar; // doesn't help
/* ... */
};
When I'm trying to call Bar() on an object of type G<D> with a E*, I get the following compile-time error:
error: no matching function for call to 'G<D>::Bar(E*&)'
note: candidates are: virtual void D::Bar(F*)
If I rename the declarations of (virtual) void Bar(F*), the code compiles fine and works as expected.
Usage:
typedef std::list<E*> EList;
typedef std::list<F*> FList;
EList es;
FList fs;
G<D> player(D());
es.push_back(new E); // times many
fs.push_back(new F); // times many
for(EList::iterator i0(es.begin()), i1(es.end()); i0 != i1; ++i0)
{
player.Bar(*i0);
}
for(FList::iterator i0(fs.begin()), i1(fs.end()); i0 != i1; ++i0)
{
player.Bar(*i0);
}
1, What's wrong with multiple overloads of member functions taking different arguments?
2, Why can't the compiler tell the difference between them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只有最派生类中包含
Bar
重写的Bar
版本才会被考虑进行重载解析,除非您添加using
声明。如果你尝试的话它应该会起作用。
Only the versions of
Bar
in the most-derived class containing an override ofBar
will be considered for overload resolution unless you add inusing
declarations. If you trythen it should work.
从您的代码中:
G
扩展了G
中的D
,Bar(E*)
上调用 <代码>G ->G
确实没有
Bar
方法,所以看看基础类
D
D
有Bar(F*)
但没有Bar(E*)
--> ;struct E
与以下类型不同struct F
所以你会得到一个错误回答你的问题:E 与 F 的类型无关,编译可以分辨出差异,这就是你收到错误的原因。
我不确定您添加了哪个 Bar,但是如果基类已经将 Bar 声明为 virtual,则扩展它的所有类都已经具有 Bar virtual,因此如果您将单词(虚拟)添加到扩展类中并不重要。
如果您展示如何实例化对象以及如何在其上调用 Bar(F*) 将会有所帮助。运行时决策取决于您如何调用方法以及传递哪些参数。
From your code:
G
extendsD
inG<D>
Bar(E*)
onG
->G
doesnot have
Bar
method so look into baseclass
D
D
hasBar(F*)
but noBar(E*)
-->struct E
is different type fromstruct F
so you get an errorTo answer your question: E is not related type to F and compile can tell the difference that's why you're getting an error.
I'm not sure which Bar you add virtual but if the base class already declares Bar as virtual all the classes that extends it already have Bar virtual so it does not matter if you add the word (virtual) into extended classes.
It would help if you showed how you instantiate your object and how you call Bar(F*) on it. There are runtime decisions that depends on how you call method and what parameters you passing.