utility实用组件学习之swap,move,forward,exchange

utility是一个实用组件库,里面包括一些非常有用的函数,比如swap,move,forwardexchange等,这篇学习这些函数的基本使用。

swap

交换两个对象的值
(函数模板)

exchange

(C++14)

将实参替换为一个新值,并返回其先前值
(函数模板)

forward

(C++11)

转发一个函数实参
(函数模板)

move

(C++11)

获得右值引用
(函数模板)

move_if_noexcept

(C++11)

若移动构造函数不抛出则获得右值引用
(函数模板)

as_const

(C++17)

获得到其实参的 const 引用
(函数模板)

declval

(C++11)

获取到其实参的引用,用于不求值语境中
(函数模板)

1.swap交换两个对象的值,示例:

#include <iostream>
#include <string>
#include <utility>

using namespace std;

class Yak {
public:
    Yak(string name = "", int h = 0, int w = 0):
        m_name(name),
        m_height(h),
        m_weight(w)
    {
        cout << "constructe============== " << this << " name= " << name << " height= " << h << " weight= " << w << endl;
    }

    ~Yak(){ cout << "destructe~~~~~~~~~~~~~~~ " << this << " name= " << this->m_name << " height= " << m_height << " weight= " << m_weight << endl;}
    
    string m_name{""};
    int m_height{0};
    int m_weight{0};
};


int main()
{
    Yak yak1;
    yak1.m_name = "yak1";
    yak1.m_height = 10001;
    yak1.m_weight = 201;

    Yak yak2;
    yak2.m_name = "yak2";
    yak2.m_height = 10002;
    yak2.m_weight = 202;

    cout << "Yak1.name= " << yak1.m_name << " Yak2.name= " << yak2.m_name << " yak1 = " << &yak1 << " yak2= " << &yak2 << endl;
    cout << "============swap=============" << endl;
    std::swap(yak1, yak2); 
    cout << "Yak1.name= " << yak1.m_name << " Yak2.name= " << yak2.m_name << " yak1 = " << &yak1 << " yak2= " << &yak2 << endl;

    cout << "Hello World!" << endl;
    return 0;

}

运行结果:

从运行结果看:交换的时候多了一个析构函数,产生了一个临时对像了吗

原来原码里的实现有T c(std::move(a)); a=std::move(b); b=std::move(c); 从这段原码可以看出交换时会产生一个临时对像c.

2.move 用于指示对象 t 可以“被移动”,即允许从 t 到另一对象的有效率的资源传递。特别是, std::move 生成标识其参数 t亡值表达式。它准确地等价于到右值引用类型的 static_cast 。

 示例:

#include <iostream>
#include <string>
#include <vector>
#include <utility>

using namespace std;


int main()
{


    string str = "Yak is mao niu";
    vector<std::string> vecStr;

    // 使用 push_back(const T&) 重载,
    // 表示我们将带来复制 str 的成本
    vecStr.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";

    // 使用右值引用 push_back(T&&) 重载,
    // 表示不复制字符串;而是
    // str 的内容被移动进 vector
    // 这个开销比较低,但也意味着 str 现在可能为空。
    vecStr.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";

    std::cout << "The contents of the vector are \"" << vecStr[0]
                                         << "\", \"" << vecStr[1] << "\"\n";


    cout << "Hello World!" << endl;
    return 0;
}

从上面的结果看,move值之后原str内容被清空了。

下面用一个类来演示它的值:

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <utility>

using namespace std;

class Yak {
public:
    Yak(string name = "", int h = 0, int w = 0):
        m_name(name),
        m_height(h),
        m_weight(w)
    {
        cout << "constructe============== " << this << " name= " << name << " height= " << h << " weight= " << w << endl;
    }

    ~Yak(){ cout << "destructe~~~~~~~~~~~~~~~ " << this << " name= " << this->m_name << " height= " << m_height << " weight= " << m_weight << endl;}
    string m_name{""};
    int m_height{0};
    int m_weight{0};
};


int main()
{
    Yak yak1;
    yak1.m_name = "yak1";
    yak1.m_height = 10001;
    yak1.m_weight = 201;

    Yak yak2;
    yak2.m_name = "yak2";
    yak2.m_height = 10002;
    yak2.m_weight = 202;

    vector<Yak> vec;
    vec.reserve(16);  //防止数据添加时重新分配
    vec.push_back(yak1);
    cout << "Yak2.name= " << yak2.m_name << " Yak2.height= " << yak2.m_height << " yak2.weight = " << yak2.m_weight << endl;
    vec.push_back(std::move(yak2));
    cout << "Yak2.name= " << yak2.m_name << " Yak2.height= " << yak2.m_height << " yak2.weight = " << yak2.m_weight << endl;

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

 为什么move之后Yak2的对象的值没有被清空呢???

参考:

工具库 - cppreference.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值