Effective C++(一个不抛出异常的swap函数)


author:

  • luixiao1223
    title: 一个不抛出异常的swap函数

来看标准STL版本的swap

namespace std{
    template<typename T>
    void swap(T& a, T& b)
    {
        T temp(a);
        a = b;
        b = temp;
    }
}

例子

class WidgetImpl{
public:
private:
    int a,b,c;
    std::vector<double> v;
};

class Widget{
public:
    Widget(const Widget& rhs);
    Widget& operator=(const Widget& rhs)
    {
        *pImpl = *(rhs.pImpl);
    }

private:
    WidgetImpl* pImpl;
};

如果你对 Widget调用swap那么实际上
pImpl是被复制的。这是十分缺乏效率的。有没有办法提高效率?

提高效率

无法通过编译

namesapce std{
    template<>
    void swap<Widget> (Widget& a,
                       Widget& b)
    {
        swap(a.pImpl, b.pImpl)
    }
}

template<>表示是一个全特化。

无法同构编译,因为a,b企图访问private

我们可以在Widget中声明一个swap public函数

class Widget{
public:
    void swap(Widget& other)
    {
        using std::swap;
        swap(this->pImpl, other.pImpl); // 错误
    }
};

namesapce std{
    template<>
    void swap<Widget> (Widget& a,
                       Widget& b)
    {
        a.swap(b);
    }
}

我们这样就解决了swap问题的效率问题了。

如果 Widget and WidgetImpl都是template class怎么办

template<typename T>
class WidgetImpl{...};

template<typename T>
class Widget{...};

错误代码

namesapce std{
    template<typename T>
    void swap<Widget<T>>(Widget<T>& a,
                         Widget<T>& b) // 错误的。
    {
        a.swap(b);
    }
}

原因: C++只允许class template的偏特化。不支持函数
templates上的偏特化。

Still Error

下面的代码是重载,不是偏特化,也不是全特化。

namespace std{
    template<typename T>
    void swap(Widget<T>& a,
              Widget<T>& b)
    {
        a.swap(b);
    }
}
  1. 错误的地方时,C++不允许向std里面添加templates。即包括classes,functions.
  2. std允许客户全特化std内的templates。偏特化可以么?

Correct

namespace WidgetStuff{
    template<typename T>
    class Widget{...};

    template<typename T>
    void swap(Widget<T>& a,
              Widget<T>& b)
    {
        a.swap(b);
    }
};

把这个重构函数放到另外的命名空间中。

using

template<typename T>
void soSomething(T& obj1, T& obj2)
{
    using std::swap;
    swap(obj1, obj2);
}

使用using是让STL的swap暴露出来。编译器会去当前命名空间找更为特殊的swap版本。如果没找到去global
space中找。然后再用这个std的swap版本。

成员版的swap绝对不要抛出异常

内置类型的操作基本不会抛出异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值