c++11 boost - ref

2018-07-13 16:12:29

ref 库定义了一个很简单的引用类型的包装器。

// Copyright (c) 2015
// Author: Chrono Law
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
//using namespace std;

#include <boost/ref.hpp>
using namespace boost;

struct square
{
    typedef void result_type;
    result_type operator()(int &x)
    {   x = x * x;  }
};

void case1()
{
    std::vector<int> v = {1,2,3,4,5};
    for_each(v.begin(), v.end(), square());
}

void case2()
{
    int x = 10;
    reference_wrapper<int> rw(x);   //包装int引用
    assert(x == rw);
    (int &)rw = 100;
    assert(x == 100);

    reference_wrapper<int> rw2(rw);
    assert(rw2.get() == 100);  //返回引用

    std::string str;
    reference_wrapper<std::string> rws(str);
    *rws.get_pointer() = "test reference_wrapper";   //返回指针
    std::cout << rws.get().size() << std::endl << std::endl;

}

//ref和 cref为工厂函数
// reference_wrapper<T>  ref(T& t);
// reference_wrapper<T const>  cref(T const& t);

void case3()
{
    double x = 2.71828;
    auto rw = cref(x);
    std::cout << typeid(rw).name() << std::endl;

    std::string str;
    auto rws = boost::ref(str);
    std::cout << typeid(rws).name() << std::endl;

    boost::cref(str);   //adl

    std::cout << std::sqrt(ref(x)) << std::endl << std::endl;
}

void case4()
{
    std::vector<int> v(10, 2) ;
    auto rw = boost::cref(v);

	//判断是否经过包装
    assert( is_reference_wrapper<decltype(rw)>::value);
    assert(!is_reference_wrapper<decltype(v)>::value);

	//解包装
    std::string str;
    auto rws = boost::ref(str);
    std::cout << typeid(unwrap_reference<decltype(rws)>::type).name() << std::endl;
    std::cout << typeid(unwrap_reference<decltype(str)>::type).name() << std::endl<<std::endl;

}

//直接解开包装,返回被包装对象的引用
void case5()
{
    std::set<int> s ;
    auto rw = boost::ref(s);
    unwrap_ref(rw).insert(12);

    std::string str("test");
    auto rws = boost::cref(str);
    std::cout << unwrap_ref(rws) << std::endl;
    
    //允许解未包装的对象,返回自身引用
    std::cout << unwrap_ref(str) << std::endl;

}

class big_class
{
private:
    int x;
public:
    big_class():x(0){}
    void print()
    {   std::cout << "big_class " << ++x << std::endl;    }
};
template<typename T>
void print(T a)
{
    for (int i = 0;i < 2; ++i)
        unwrap_ref(a).print();
}
void case6()
{
    big_class c;
    auto rw = ref(c);
    c.print();

    print(c);
    print(rw);
    print(c);
    c.print();
}

//标准库
void case7()
{
    using namespace std;

    typedef double (*pfunc)(double);
    pfunc pf = sqrt;
    cout << std::ref(pf)(5.0) << endl; //包装函数指针

    square sq;
    int x =5;
    std::ref(sq)(x);   //包装函数对象
    cout << x << endl;

    vector<int> v = {1,2,3,4,5};
    for_each(v.begin(), v.end(), std::ref(sq));
}


int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
}
[root@192 c++]# g++ -std=c++11 main.cpp 
[root@192 c++]# ./a.out 
22

N5boost17reference_wrapperIKdEE
N5boost17reference_wrapperISsEE
1.64872

Ss
Ss

test
test
big_class 1
big_class 2
big_class 3
big_class 2
big_class 3
big_class 4
big_class 5
big_class 4
2.23607
25


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/b1


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。