gpt4 book ai didi

c++ - 函数模板和常规重载

转载 作者:搜寻专家 更新时间:2023-10-31 01:27:08 26 4
gpt4 key购买 nike

以下代码有几个常规函数重载,并且 - 现在 - 一个模板函数,如果没有合适的重载,则用作万能的。

几乎如我所愿地工作,除了使用派生类(之前在常规重载中结束)改为由函数模板处理。

#include <iostream>

class Base { };
class AnotherBase { };

class Derv : public Base{ };

class Derv2 : public Base { };

class DervDerv : public Derv { };

void f(const Base &b)
{
printf("b(Base)\n");
}

void f(const Derv &b)
{
printf("b(Derv)\n");
}

template<class T> void f(const T& t)
{
printf("b(template)\n");
}

int main() {
f(Base());
f(AnotherBase());
f(Derv());
f(Derv2());
f(DervDerv());

return 0;
}

所以我得到的输出是这样的......

b(Base)
b(template)
b(Derv)
b(template)
b(template)

...当我天真地期望是这样的时候:

b(Base)
b(template)
b(Derv)
b(Base)
b(Derv)

基类的函数重载真的比函数模板更“低质量”吗?如果是这样,是否有一种简单的方法来改变它?

https://ideone.com/jD2lgz

最佳答案

这与“质量”无关。它是关于转换的,就像任何其他重载一样。要对 f(Derv2()); 的调用进行重载解析,编译器将从您的函数模板中合成如下声明:

void f(const Derv2& t);

它与其他声明的重载相对立。选择此重载的原因完全相同 f(const Derv &)f(const Base &) 更匹配,当您编写 f(Derv( ));.

“包罗万象”的模板就可以做到这一点,它会捕获没有确切的用户定义重载的所有内容。如果你想防止这种情况,你需要用元编程来约束模板。一个依赖 SFINAE 的简单技巧如下所示:

template<class T>
auto f(const T& t) -> std::enable_if_t<!std::is_convertible<T*, Base*>::value>
{
printf("b(template)\n");
}

产生 exact output you expected .虽然很明显,您需要提前知道要限制什么。

关于c++ - 函数模板和常规重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53977457/

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