重载解析,模板和继承 [英] Overload resolution, templates and inheritance
问题描述
#include <iostream>
struct A {};
struct B : public A {};
template<typename T>
void foo(const T &x) { std::cout << "Called template" << std::endl; }
void foo(const A &a) { std::cout << "Called A" << std::endl; }
int main()
{
foo(A());
foo(B());
return 0;
}
打印:
Called A
Called template
在一个合适的非模板函数将总是在模板函数上被选择的印象。有人可以向我解释导致这个令人惊讶的结果的解决步骤吗?
I was under the impression that a suitable non-template function would always be chosen over a template function. Can someone explain to me the resolution steps that lead to this somewhat surprising result?
推荐答案
在模板函数下总是选择合适的非模板函数。
I was under the impression that a suitable non-template function would always be chosen over a template function.
这只适用于模板和非模板是同样好的候选人。这就是为什么为 foo(A())
选择非模板的原因。
This only holds if the template and the non-template are equally good candidates. That's why the non-template is chosen for foo(A())
.
foo(B())
,使用非模板需要一个派生到基础的转换。
However, in the case of foo(B())
, using the non-template requires a derived-to-base conversion. So the function template is strictly better, and hence it's chosen.
foo
模板实例化为 void foo(const B&)
。考虑没有模板的样子:
The foo
template instantiates into void foo(const B&)
. Consider what it would look like without templates:
void foo(const B &x) { std::cout << "Called template" << std::endl; }
void foo(const A &a) { std::cout << "Called A" << std::endl; }
我相信你会同意调用 foo / code>应明确选择第一个。这就是为什么选择模板。
I believe you'll agree calling foo(B())
should unambiguously pick the first one. That's exactly why the template is chosen.
这篇关于重载解析,模板和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!