什么时候更喜欢普通函数重载而不是模板(重载)?

When to prefer plain function overload over templates (overload)?

我无法google得出这个问题的答案。

什么时候应该使用模板、模板重载和普通函数重载?

我更喜欢总是使用模板,感觉打字更少,代码更通用,但我开始质疑自己,为什么我们有模板时人们还要使用函数重载。

我看到的唯一区别是,在模板的情况下,默认模板声明将处理特殊情况不会处理的所有情况,而对于普通函数,我们将不得不编写至少两倍的代码。

同样在下面的第 3 个示例中,有时一个模板就足够了。 所以这里的主要问题是为什么要为普通函数重载而烦恼?

例如:

void func(int param)
{
    // ...
}

void func(double param)
{
    // ...
}

void func(char param)
{
    // ...
}

同样可以用模板实现:

template<typename T>
void tmpl(T param)
{
    // ...
}

template<>
void tmpl(double param)
{
    // ...
}

template<>
void tmpl(char param)
{
    // ...
}

在大多数情况下,我们甚至不需要重载模板,因为我们关心的只是确保数据类型大小正确,同时函数的算法相同。

所以在这些情况下我们可以这样写:

template<typename T>
void tmpl(T param)
{
    // ...
}

虽然使用普通函数,但我们需要做更多的工作。

编辑: 我找到了 this 很好的答案,它有点相关但没有完全涵盖我的问题:

模板特化和重载之间的一大区别是,重载允许参数的隐式转换,而模板特化则不允许。继续您的示例,如何处理 float 参数? func(double param) 将被选中,但通用模板将被实例化。通常前者是正确的。

更一般地说,有理由更喜欢 non-template 代码。模板通常必须驻留在 header 中,这会减慢编译速度并向所有人公开实现。模板会导致更隐蔽的编译错误消息,并且工具不能很好地支持它。例如。 Visual studio 2015 不提供模板的智能感知信息。