gpt4 book ai didi

c++ - 模板特化 VS 函数重载

转载 作者:IT老高 更新时间:2023-10-28 13:57:26 27 4
gpt4 key购买 nike

一本教科书我注意到您可以通过模板特化或函数重载为标准库函数(如 swap(x,y))提供自己的实现。这对于任何可以从赋值交换以外的东西中受益的类型都很有用,例如 STL 容器(我知道,它们已经编写了交换)。

我的问题如下:

  1. 更好的是:模板特化,让您的特化交换实现,或函数重载提供确切的您希望在没有模板的情况下使用参数?

  2. 为什么更好?或者如果他们是平等的,为什么会这样?

最佳答案

简短的故事:尽可能重载,在需要时专攻。

长话短说:C++ 对待特化和重载的方式非常不同。这最好用一个例子来解释。

template <typename T> void foo(T);
template <typename T> void foo(T*); // overload of foo(T)
template <> void foo<int>(int*); // specialisation of foo(T*)

foo(new int); // calls foo<int>(int*);

现在让我们交换最后两个。

template <typename T> void foo(T);
template <> void foo<int*>(int*); // specialisation of foo(T)
template <typename T> void foo(T*); // overload of foo(T)

foo(new int); // calls foo(T*) !!!

编译器在查看特化之前就进行了重载解析。因此,在这两种情况下,重载决议都选择 foo(T*) .然而,只有在第一种情况下它才找到 foo<int*>(int*)因为在第二种情况下 int*特化是 foo(T) 的特化,而不是 foo(T*) .


你提到了std::swap .这让事情变得更加复杂。

标准规定您可以将特化添加到 std命名空间。太好了,所以你有一些 Foo类型,它有一个性能交换,然后你只需要专门 swap(Foo&, Foo&)std命名空间。没问题。

但是如果 Foo是模板类吗? C++ 没有函数的部分特化,所以你不能特化 swap .您唯一的选择是重载,但标准规定您不允许将重载添加到 std 中。命名空间!

此时您有两个选择:

  1. 创建一个swap(Foo<T>&, Foo<T>&)在您自己的命名空间中运行,并希望通过 ADL 找到它。我说“希望”是因为如果标准库像 std::swap(a, b); 这样调用交换那么 ADL 根本不起作用。

  2. 忽略标准中说不要添加重载的部分,无论如何都要这样做。老实说,即使在技术上不允许这样做,但在所有现实场景中它都会起作用。

但要记住的一点是,不能保证标准库使用 swap一点也不。大多数算法使用 std::iter_swap在我看过的一些实现中,它并不总是转发到 std::swap .

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

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