Modern C++ std::swap的实现原理

前言

之前我们研究了std::bind, std::move的实现原理,如有兴趣可以往前翻翻。本节讨论下std::swap, 也比较简单。

实现代码

/usr/include/c++/8/bits/move.h

158 #define _GLIBCXX_MOVE(__val) std::move(__val)

178 #if __cplusplus >= 201103L
179     typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
180       is_move_constructible<_Tp>,
181       is_move_assignable<_Tp>>::value>::type
182     swap(_Tp& __a, _Tp& __b)
183     noexcept(__and_<is_nothrow_move_constructible<_Tp>,
184             is_nothrow_move_assignable<_Tp>>::value)
185 #else
186     void
187     swap(_Tp& __a, _Tp& __b)
188 #endif
189     {
190       // concept requirements
191       __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
192
193       _Tp __tmp = _GLIBCXX_MOVE(__a);
194       __a = _GLIBCXX_MOVE(__b);
195       __b = _GLIBCXX_MOVE(__tmp);
196     }

可见,是通过一个中间变量来交换的,相当于:

_Tp __tmp = std::move(__a);

__a = std::move(__b);

__b = std::move(__tmp);

交换条件

这里使用了SFINAE (Substitution Failure Is Not An Error)有条件的激活swap,如果你的对象不是可移动的且编译标准大于等于c++11,也没法swap,例如:

#include<iostream>
using namespace std;

class NotSwappableType {
public:
    NotSwappableType() = default;

    // Delete move constructor and move assignment operator
    NotSwappableType(NotSwappableType&&) = delete;
    NotSwappableType& operator=(NotSwappableType&&) = delete;
};

int main(){
        int a=1;
        int b=2;
        std::swap(a,b);
        std::cout<<"a="<<a<<" b="<<b<<std::endl;

        NotSwappableType nm1,nm2;
        std::swap(nm1,nm2);
}

则会编译失败。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山老宅

鸡蛋不错的话,要不要激励下母鸡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值