函数重载和模板函数有什么区别?哪个更合适?

What is the difference between function overloading and template function? Which is more appropriate?

本文关键字:函数 什么 重载 区别      更新时间:2023-10-16
template<>std::string Add(std::string x ,std::string y)
{
return x.append(y);
}
std::string Add(std::string x ,std::string y)
{
return x.append(y);
}

如果我们可以使用函数重载来专门化代码,为什么需要模板专用化?

如果我们可以使用函数重载来专门化代码。为什么需要模板专业化

因为是不同的东西,不同的行为。

一个实际的例子。

以下示例编译和链接没有问题

#include <string>
void foo (std::string const &)
{ }
int main ()
{
foo("abc");
}

请注意,"abc"可以转换为std::string但不是std::string(是char const [4](。

因此,调用常规(非模板(函数时,必要时会转换参数。

观察以下代码

#include <string>
template <typename T>
void foo (T const &);
template <>
void foo (std::string const &)
{ }
int main ()
{
foo("abc");
}

现在代码编译但不链接:foo()是一个模板(仅声明(模板函数,仅定义了std::string完全专用化。

这一次,编译器推导出参数的类型(char const [4],不同于std::string(,所以给出了一个行错误,因为没有定义foo()的通用版本。

通过这种方式,您可以强制规定只能使用std::string调用foo(),而不能使用可转换为std::string的值调用。

你可以得到同样的东西,混合重载和模板,获得编译(不链接(错误如下

#include <string>
template <typename T>
void foo (T const &) = delete;
void foo (std::string const &)
{ }
int main ()
{
foo("abc");
}

现在非模板foo()可以(理论上(接受char cont [4]被声明(并删除(模板版本。因此,再次考虑到char const [4]不是std::string,编译器优先于模板版本。该内容已删除。所以编译错误。

因为根据用例,您有时会编写通用的容器/函数,即它们适用于每种类型。比如std::vector.但是,当您执行std::vector<string>std::vector<const char*>(虽然两者都表示字符串(时,向量的含义并不相同,因为一个存储字符串,另一个存储指向以 null 结尾的字符串的指针。那么,从设计的角度来看,您将如何解决这个问题呢?

好吧,你要么忽略此类型的问题,要么阻止使用此类型,要么编写一个专用化,使此容器以不同的方式为此类类型工作,以实现您的设计目的。同样,你为函数编写一个专用化,这取决于你试图解决的问题。

因此,这些模板专业化是为了解决特定类型的问题。如果您不需要它,请不要使用它。您不需要无缘无故地使您的代码复杂化。

这取决于用例。 考虑一个函数 Add((,它排除两个变量并返回总和。现在,根据用例,这两个变量可以是整数或浮点数。这可以通过以下两种方式实现:

Template <typename T>
T Add(T x, T y)
{
return x + y;
}

或者,您可以分别编写两个函数。一个用于整数,一个用于浮点参数。

int Add(int x, int y)
{
return x + y;
}

float Add(float x, float y)
{
return x + y;
}