C boost bind的一些用法

2021-08-09 06:15:01 字數 4958 閱讀 5669

沒有對c++了解特別深入吧,還是對有些特性用法之類的不是很熟悉,閱讀**的時候還是碰到很多不明白。

下面是lz讀到的一句**

boost:

:functionpcl:

:pointcloud::pointxyzrgba>::constptr &> f = boost:

:bind(&mainloop::onnewcloud, this, _1);

boost::bind的用法目的

boost :: bind是標準函式std :: bind1st和std :: bind2nd的泛化。 它支援任意函式物件,函式,函式指標和成員函式指標,並且能夠將任何引數繫結到特定值或將輸入引數路由到任意位置。 bind對函式物件沒有任何要求; 特別地,它不需要result_type,first_argument_type和second_argument_type標準typedef。

通過函式或者函式指標使用bind

int f(int a, int b)

int g(int a, int b, int c)

bind(f, 1, 2)會產生乙個零元函式,它不接受引數並且返回f(1, 2)。類似的,bind(g, 1, 2, 3)( )等同於g(1, 2, 3)。

可以選擇性地繫結一些引數。 bind(f,_1,5)(x)等價於f(x,5); 這裡_1是乙個佔位符引數,意思是「用第乙個輸入引數替換」。

為了比較,這裡是與標準庫原語相同的操作:

std:

:bind2nd(std:

:ptr_fun(f), 5)(x);

bind也包含std :: bind1st的功能:

std:

:bind1st(std:

:ptr_fun(f), 5)(x); //f(5, x)

bind(f, 5, _1)(x);//f(5, x)

bind可以處理具有兩個以上引數的函式,其引數替換機制更為通用:

bind(f, _2,_1)(x, y); //f(y, x)

bind(g, _1, 9, _1)(x); //g(x, 9, x)

bind(g, _3, _3, _3)(x, y, z); //g(z, z, z)

bind(g, _1, _1, _1)(x, y, z); //g(x, x, x)

請注意,在最後乙個示例中,由bind(g,_1,_1,_1)生成的函式物件不包含超出第乙個引數的引用,但仍可以使用多個引數。 任何額外的引數被預設忽略,就像第乙個和第二個引數在第三個例子中被忽略。

繫結的引數被返回的函式物件複製並儲存在內部。 例如,在以下**中:

int i = 5;

bind(f, i, _1);

i的值的副本儲存在函式物件中。 boost :: ref和boost :: cref可用於使函式物件儲存對物件的引用,而不是副本:

int i = 5;

bind(f, ref(i), _1);

bind(f, cref(i), _1);

通過函式物件使用bind

繫結不限於功能; 它接受任意函式物件。 在一般情況下,必須明確指定生成的函式物件的operator()的返回型別(不使用typeof運算子,不能推斷返回型別):

struct f

bool

operator()(long a, long b)

};f f;

int x = 104;

bind(f, _1, _1)(x); //f(x, x), i.e. zero

一些編譯器遇到bind r(f,…)語法時遇到麻煩。 由於可移植性原因,支援表達上述的替代方法:

boost:

:bind(boost:

:type(), f, _1, _1)(x);

但請注意,備用語法僅作為解決方法提供。 它不是介面的一部分。

當函式物件公開乙個名為result_type的巢狀型別時,可以省略顯式返回型別:

int x = 8;

bind(std:

:less(), _1, 9)(x); //x

<9

[注意:省略返回型別的能力在所有編譯器上都不可用]

預設情況下,bind將提供所提供的函式物件的副本。 boost :: ref和boost :: cref可用於使其儲存對函式物件的引用,而不是副本。 當函式物件不可複製,複製昂貴或包含狀態時,這可能很有用; 當然,在這種情況下,程式設計師期望確保功能物件在使用時不被銷毀。

struct f2

};f2 f2 = ;

int a = ;

std::for_each(a, a+3, bind(ref(f2), _1));

assert(f2.s == 6);

上面**的目的是把a中的每個元素相加,求和結果儲存到結構體f2.s中。

通過指向成員的指標使用bind

指向成員函式的指標和資料成員的指標不是函式物件,因為它們不支援operator()。 為方便起見,繫結接受成員指標作為其第乙個引數,並且行為就好像已經使用boost :: mem_fn將成員指標轉換為函式物件。 換句話說,表達為

bind(&x::f, args)
等價於

bind

(men_fn(&x::f), args)

其中r是x :: f(用於成員函式)的返回型別或成員的型別(對於資料成員)。

[注意:mem_fn建立能夠接受指向物件的指標,引用或智慧型指標作為其第乙個引數的函式物件; 有關其他資訊,請參閱mem_fn文件。]

舉例如下:

struct x

;x x;

shared_ptrp(new x);

int i = 5;

bind(&x::f, ref(x), _1)(i);

bind(&x::f, &x, _1)(i); //(&x)->f(i)

bind(&x::f, x, _1)(i); //(internal copy of x).f(i)

bind(&x::f, p, _1)(i); //(internal copy of p)->f(i)

最後兩個例子很有趣,因為它們產生「自包含」功能物件。 bind(&x :: f,x,_1)儲存x的副本。 bind(&x :: f,p,_1)儲存p的副本,由於p是乙個boost :: shared_ptr,函式物件保留對其x例項的引用,並且即使p超出範圍也將保持有效, 是reset()。

對於函式組合使用巢狀binds(感覺這個翻譯好奇怪!)

傳遞給繫結的一些引數可能是巢狀繫結表示式本身:

bind(f, bind(g, _1))(x); //f(g(x))
內部繫結表示式在呼叫函式物件之前以非特定順序進行外部繫結之前的計算; 當外部繫結被評估時,評估結果將被替換為它們的位置。 在上面的例子中,當使用引數列表(x)呼叫函式物件時,首先評估bind(g,_1)(x),得到g(x),然後bind(f,g(x)) x),得到最終結果f(g(x))。

繫結的這個特徵可以用來執行功能組合。 有關示例演示如何使用bind實現與boost.compose類似的功能的示例,請參見bind_as_compose.cpp。

請注意,第乙個引數 - 繫結函式物件 - 不被評估,即使它是由bind或佔位符引數生成的函式物件,因此下面的示例不能按預期方式工作:

typedef

void (*pf)(int);

std::vector

v;std::for_each(v.begin(), v.end(), bind(_1, 5));

typedef

void(*pf)(int)

std::vector

v;

雖然第乙個引數是,預設情況下不進行評估,但所有其他引數都是。 有時候,有必要在第乙個之後評估引數,即使它們是巢狀的繫結子表示式。 這可以通過另乙個函式物件的幫助來實現,保護,掩飾型別,以便繫結不能識別和評估它。 被呼叫時,保護簡單地將引數列表**到其他函式物件。

標頭檔案protect.hpp包含乙個保護的實現。 為了保護繫結函式物件免於評估,請使用protect(bind(f,…))。

過載操作符(new in boost1.33)

為方便起見,通過繫結過載邏輯非運算子產生的函式物件! 和關係和邏輯運算子==,!=,<,<=,>,> =,&&,||。

!bind(f,…)等價於bind(logical_not(),bind(f,…)),其中logical_not是乙個函式物件,它接受乙個引數x並返回!x。

bind(f,…)op x,其中op是關係或邏輯運算子,相當於bind(relation(),bind(f,…),x),其中,關係是乙個函式物件,需要兩個 引數a和b並返回乙個操作b。

這在實踐中意味著你可以方便地否定繫結的結果:

std::remove_if(first, last, !bind(&x::visible, _1));//remove invisible objects
並將繫結的結果與值進行比較:

std::find_if(first, last, bind(&x::name, _1) == "peter" || bind(&x::name, _1) == "paul");

針對佔位符:

bind(&x::name, _1) == _2
或者針對另外乙個佔位符:

std::sort(first, last, bind(&x::name, _1)< bind(&x::name, _2));//sort by name

的一些用法

action標籤,顧名思義,是用來呼叫action的標籤,在jsp中頁面中,可以具體指定某一命名空間中的某一action。而標籤的主體用於顯示及渲染actionr的處理結果。action標籤有如下幾個屬性 id 可選屬性,作為該action的引用id name 必選屬性,指定呼叫action nam...

IImage的一些用法

因為美工做出來的圖是png24,帶alpha通道透明的,用傳統的bitblt方法沒有辦法顯示 可能是本人比較笨啦,哈哈 所以採用了iimage的方法來進行畫圖。使用iimage的draw的方法時,要畫區域性是發現總是不對,查了一下msdn,發現是如下的問題。optional const rect s...

gcc 的一些用法

gcc編譯多個原始檔 一.常用編譯命令選項 假設源程式檔名為test.c。3.選項 e 用法 gcc e test.c o test.i 作用 將test.c預處理輸出test.i檔案。4.選項 s 用法 gcc s test.i 作用 將預處理輸出檔案test.i彙編成test.s檔案。5.選項 ...