gpt4 book ai didi

c++ - 使用子类调用时重载函数模板匹配模板而不是基类

转载 作者:太空宇宙 更新时间:2023-11-04 16:03:46 25 4
gpt4 key购买 nike

考虑以下代码:

#include <cstdlib>
#include <iostream>

using std::cout;
using std::endl;

class A {
public:
virtual ~A() {

}
};

class B : public A {

};

void foo(A& a) {
cout << "A&" << endl;
}

void foo(const A& a) {
cout << "const A&" << endl;
}

void foo(A* a) {
cout << "A*" << endl;
}

void foo(const A* a) {
cout << "const A*" << endl;
}

template <class T>
void foo(T& a) {
cout << "T&" << endl;
}

template <class T>
void foo(const T& a) {
cout << "const T&" << endl;
}

template <class T>
void foo(T* a) {
cout << "T*" << endl;
}

template <class T>
void foo(const T* a) {
cout << "const T*" << endl;
}

int main(int argc, char** argv) {
B a;
foo(a);

B& b = a;
foo(b);

B* c = &a;
foo(c);

const B& d = a;
foo(d);

const B* e = &a;
foo(e);

return EXIT_SUCCESS;
}

产生以下输出:

T&
T&
T*
const T&
const T*

这个输出让我感到惊讶,因为我认为最接近匹配的函数将被调用。所以我期待输出:

A&
A&
A*
const A&
const A*

有人可以解释为什么当我传入基类 (A) 的子类 (B) 时选择模板函数重载而不是基类重载吗?

最佳答案

这是预期的行为。当你调用 foo(a); 时,a 是一个 B。所以我们需要从 BA 的隐式转换,以便调用 void foo(A& a)。但是因为你也有

template <class T>
void foo(T& a) {
cout << "T&" << endl;
}

模板被删除,你得到 void foo(B& a)。这是直接匹配,不需要转换。这是最好的功能,所以这就是它被选中的原因。这对于所有其他函数都是相同的,T 被推导为 B,这比所有 A 函数提供更好的匹配.

如果你想停止这个,你可以使用 std::enable_if并检查类型是否为派生类 std::is_base_of

关于c++ - 使用子类调用时重载函数模板匹配模板而不是基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39044153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com