C++_std::函数, addressof,ref,cref,reference_wrapper

catalog

  • std::as_const
  • std::addressof
  • std::reference_wrapper, std::ref, std::cref

std::as_const

伪代码:

template <class _T>
const _T & as_const( _T & _t){
    return _t;
}

他不会创建新的对象, 也不会修改原对象;

vector< int> arr = {1, 2, 3};

for( int & i : std::as_const( arr)) ' 错 '

std::addressof

_Tp * addressof(_Tp& __r){ return std::__addressof(__r);}

const _Tp * addressof( const _Tp &&) = delete;  ' 不允许对右值的取地址 '

其实就是 & 取地址, 封装成函数, 比较好;
代码长了, 一个&号, 很容易看不见 或忽略… 这样封装性比较好;

std::reference_wrapper, std::ref, std::cref

T & ref = obj;
这里的引用符号&, 和上面取地址时的问题一样, 一个符号 很容易看不见或丢失… 封装成函数/类, 更符号高级语言的风格.

class reference_wrapper{
	_Tp * _M_data;
public:
	reference_wrapper( _Tp & _d)
		: _M_data( std::__addressof( _d)){}
	
	reference_wrapper(_Tp&&) = delete;  ' 不允许对右值的引用 '
	
	operator _Tp&(){ return this->get();}  ' 可以强转为: _Tp & 引用 '
	
	_Tp & get(){ return *_M_data;}
};

顾名思义, 他是对T & 这个引用, 做了一层封装;


reference_wrapper<_Tp> ref(_Tp& __t){ return reference_wrapper<_Tp>(__t); }

reference_wrapper< const _Tp> ref( const _Tp& __t){ return reference_wrapper< const _Tp>(__t); }

void ref(const _Tp&&) = delete;
void cref(const _Tp&&) = delete;  ' 不允许对右值的引用 '

ref 和 cref, 就类似于一个宏, 他的本质 就是构造一个reference_wrapper对象;


void func( const T & _t){}

T t;
reference_wrapper< T> ref = t;
func( ref);  ' ref会强转为 T&类型; '
func( ref.get());

func( std::ref( t));
func( std::cref( t)); ' 一般这2种用的比较多 '

这样, 你使用std::ref( t) 或 cref( t), 你一看就可以看出, 这传递的是引用/const引用;


当然, reference_wrapper的作用 不仅于此, 他的功能 暂时还了解不全
比如, 线程函数的参数, 比如是引用参数; 你传递( obj) 他其实不是引用传递, 而是会copy一份副本!!! 并不是引用
std::ref( obj), 他是真正的引用传递

你可能感兴趣的:(计算机知识,c++,开发语言,后端)