Swap() 函数的什么实现更好,适用于什么情况

What implementation of Swap() function is better and for what situations?

本文关键字:更好 适用于 什么情况 实现 什么 函数 Swap      更新时间:2023-10-16

我定义了两个函数:

1).

template<class T> inline
void swap(T &first, T &second)
{   
    if (&first != &second)
    {
        T tmp = first;
        first = second;
        second = tmp;
    }
}

2).

template<typename T>
inline void SwapMe(T *first, T *second)
{
    if(*first != *second)
    {
        T tmp = *first;
        *first = *second;
        *second = tmp;
    }
}

哪个实现更好(第一个等于 std::swap() )?

第一个版本最好使用通过引用传递或按值传递的变量。

第二个更适合指向值的指针。

它们是不同的,因为引用与指针是不同的动物。

除了第一个,两者都不好,因为我更喜欢它。 其他人会更喜欢第二个,因为他们认为应该在调用者的末尾明确说明函数可能会修改其参数。 我认为,如果你不知道函数做什么,就不应该调用函数,它们做什么应该从它们的名字上看出来,就像交换一样。 我还认为,C++中原始指针的唯一目的是作为非拥有、可重新定位和/或可无效的引用。 除非有必要实现自己的内存管理类,例如标准库中的类。

没有人说案例 2 是危险的。如果您的代码将包含 NULL 指针,您是否会收到程序崩溃:交换我(空、空)

有一个

标准函数模板与您的swap大致相同(即std::swap),并且有一个标准函数模板与您的SwapMe大致相同(即std::iter_swap)。

两者都不是真正的"更好",它们各有用途。它们中的任何一个都可以使用另一个来实现,但是在标准iter_swap中发生时,它是根据swap定义的,因此swap被认为是更基本的操作。对于自己的类型,ADL 过载是swap的。

在代码中,SwapMe中的*first != *second测试非常可疑。它需要T才能有operator!=,而且考虑到某些类型的!=可能很慢,它并不是一个很大的优化,所以它为常见情况增加了相当大的成本(当对象不相等时)。此外,根据类型T的定义,交换相等的对象可能会产生影响(例如,在vector的情况下,容量不参与相等比较,但在使用 std::swapvector::swap 交换时交换)。所以目前SwapMe更糟,但我怀疑这不是故意的:-)

事实上,swap函数中的任何此类测试都是可疑的,因为它往往会减慢常见情况的速度,即使只是几分钟。但是,如果您使测试相同,那么它们是否应该存在与参数类型应该是什么是一个单独的参数。