C ++:重载不会选择预期的方法(C++: overloading does not choose expected method)

编程入门 行业动态 更新时间:2024-10-18 20:30:52
C ++:重载不会选择预期的方法(C++: overloading does not choose expected method)

我有以下代码:

#include <iostream> #include <vector> using namespace std; struct A{}; struct B: public A {}; template <typename T> void foo(const T& obj) { cerr << "Generic case"<< endl;} void foo(const A& a) { cerr << "Specific case" << endl; } int main() { vector<int> v; foo(v); B b; foo(b); A a; foo(a); }

输出是

通用案例 通用案例 具体情况

为什么没有为B对象选择foo(const A& a) ?

奇怪的是,如果我删除了模板化方法并且只是具有以下内容:

#include <iostream> #include <vector> struct A{}; struct B: public A {}; //template <typename T> //void foo(const T& obj) { cerr << "Generic case"<< endl;} void foo(const A& a) { cerr << "Specific case" << endl; } int main() { B b; foo(b); A a; foo(a); }

代码编译,输出为:

Specific case Specific case

为什么模板化方法的存在会产生这样的差异?

编辑:如何在存在模板化方法的情况下强制编译器为从A派生的类选择自由方法?

I have the following code:

#include <iostream> #include <vector> using namespace std; struct A{}; struct B: public A {}; template <typename T> void foo(const T& obj) { cerr << "Generic case"<< endl;} void foo(const A& a) { cerr << "Specific case" << endl; } int main() { vector<int> v; foo(v); B b; foo(b); A a; foo(a); }

Output is

Generic case Generic case Specific case

Why is it that foo(const A& a) is not being chosen for the B object ?

Curiously enough, if I removed the templated method and just have the following:

#include <iostream> #include <vector> struct A{}; struct B: public A {}; //template <typename T> //void foo(const T& obj) { cerr << "Generic case"<< endl;} void foo(const A& a) { cerr << "Specific case" << endl; } int main() { B b; foo(b); A a; foo(a); }

The code compiles and the output is:

Specific case Specific case

Why is the presence of the templated method making such a difference?

Edit: How can I force the compiler to choose the free method for classes derived from A in the presence of the templated method?

最满意答案

对foo(const B&)的调用不需要转换,模板实例化会产生这种转换,因此它是更好的匹配。

当编译器看到函数调用时,必须实例化每个基函数模板,并将其与每个正常函数一起包含在重载集中。 之后执行重载解析。 还有SFINAE,它允许实例化函数模板以导致错误(这样的函数不会被添加到过载集中)。 事实上,事情并非如此简单,但它应该给出一般情况。

关于你的编辑:只有一种方法可以调用。 还有什么可以作为输出?

No conversion is necessary for the call to foo(const B&) which the template instantiation yields thus it is the better match.

When a function call is seen by the compiler, every base function template has to be instantiated and is included in the overload set along with every normal function. After that overload resolution is performed. There is also SFINAE, which allows an instantiation of a function template to lead to an error (such a function would not be added to the overload set). Of course, things aren't really that simple, but it should give the general picture.

Regarding your edit: There is only one method to call. What else could there be as output?

更多推荐

本文发布于:2023-08-05 03:55:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1428111.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法   overloading   choose   expected   method

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!