boost 原始碼 ref 庫分析

2021-06-20 11:42:04 字數 1637 閱讀 6421

引用檔案: boost/ref.hpp

一般情況下,泛型演算法中的函式物件,傳值語義是可行的,但是也有很多特殊情況,作為引數的函式物件拷貝代價過高(具有複雜的內部狀態),或者不希望拷貝物件(內部狀態不應該被改變),甚至拷貝是不可行的(noncopyable,單件)。

boost.ref應用**模式,引入物件引用的包裝器概念解決了這個問題。

t& get() const

t* get_pointer() const

private:

t* t_;};

從**中可以看出,其實就是儲存了所封裝的物件的指標。所以可以達到拷貝甚至快速拷貝的目的。

boost::addressof 的實現就是取該物件的位址。

templatet * addressof( t & v )

boost::detail::addr_impl_ref 簡單的物件封裝。不可賦值拷貝。而addressof_impl的實現如下

templatestruct addressof_impl

static inline t * f( t * v, int )

};

f函式的實現,如此費工夫轉換來轉換去,目的是防止自定義的operator t*() 的操作符過載。

參見如下示例。

vecint vecint;

int intarray = ;

vecint.assign(intarray,intarray+_countof(intarray));

boost_auto(rw1,boost::ref(vecint));

std::cout << typeid(rw1).name() << std::endl;

std::cout << rw1.get()[0] << std::endl;

std::cout << unwrap_ref(rw1)[1] << std::endl;

看看ref()的定義

簡單的封裝,

解封裝函式unwrap_ref定義如下

template inline typename unwrap_reference::type&

unwrap_ref(t& t)

因為返回值是不參與型別推演的。所以有了unwrap_reference模板,另外typename關鍵字不能少,否則type會被當作unwrap_reference的成員變數,而不是乙個型別。

【補】對於這個例子

std::cout << unwrap_ref(rw1)[1] << std::endl;

template\

: public mpl::true_ \

; \\

template\

class unwrap_reference< x > \

; \/**/

#if !defined(boost_no_cv_specializations)

#endif

可以看出,通過返回值的偏特化,獲取裡面最原始的型別。

以上分析權當學習筆記以記之。

centos 原始碼編譯安裝boost庫

執行命令mkdir boostrec建立資料夾。執行命令cd進入boostrec資料夾下。2 解壓檔案 tar zxvf boost 1 63 0.tar.gz 3 執行命令.bootstrap.sh 預設的boost標頭檔案安裝到 usr local include 資料夾下。boost庫檔案會安...

Boost 原始碼分析筆記1 remove cv

remove cv 這個模版類能夠幫我們去掉型別的const,他的實現很簡單,即使用模版元技術 template class t struct remove cv template class t struct remove cv template class t struct remove cv ...

Boost 原始碼分析筆記2 is array

喜歡這篇文章嗎?喜歡的話去看博主的置頂部落格,即可依據分類找到此文章的原版得到更好的體驗,title boost 原始碼分析筆記2 is array mathjax true date 2020 03 17 15 19 27 categories c 筆記,boost原始碼分析筆記 tags c 筆...