Swap()函数的哪些实现更好,哪种情况更好?

时间:2013-01-23 04:32:55

标签: c++ templates stl std swap

我定义了两个函数:

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())?

4 个答案:

答案 0 :(得分:1)

对于通过引用传递或通过值传递的变量,第一个版本更好。

对于指向值的指针,第二个更好。

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

答案 1 :(得分:1)

除了第一个之外,两者都没有更好,因为我更喜欢它。其他人会更喜欢第二个,因为他们认为应该在调用者的最后明确一个函数可能会修改它的参数。我的想法是,如果你不知道他们做了什么,你不应该调用函数,他们所做的事情应该是他们的名字显而易见的,就像swap的情况一样。我还认为,C ++中原始指针的唯一目的是作为非拥有,可重新访问和/或可归属的引用。除非您必须实现自己的内存管理类,例如标准库中的类。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

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

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

事实上,swap函数中的任何此类测试都是可疑的,因为即使只是微不足道,它也会减慢常见情况。但是如果你使测试相同,那么它们是否应该存在就是参数类型应该是一个单独的参数。