天天看點

bind2nd如何使用_解析bind1st和bind2nd的使用

解析bind1st和bind2nd的使用

1、首先看一個容器的操作:

void f(std::vector &vect)

{

std::vector::iterator firstOne;

for (firstOne = vect.begin();

firstOne != vect.end();

++firstOne)

{

doSomething(*firstOne, "Some string literal");

}

}

這個f調用就是完成對容器vect的疊代,並在疊代過程中,處理iter值和一個不變的字元串,至於dosomething完成什麼功能,根本不必關心。

這裡有人肯定要說,不是用for_each就可完成這種功能嗎,可for_each隻接受一個參數的函數。如下所示:

funcation for_each(iterator beg_it, iterator end_it, funcation func);

那麼怎樣讓func能夠綁定當前iterator值和一個不變的字元串呢?如果成功,問題就OK了。

在解決這個問題必須要用到適配器函數,如bind1nd, bind2st之流的捆綁函數。在解析這兩個函數之前,先看看Funcation的類聲明:

2、Funcation的類聲明:

template

struct binary_function {

typedef Arg first_argument_type;

typedef Arg2 second_argument_type;

typedef Res result_type;

};

ok, 我們自己的func也可繼承這個基類,哈哈,改進後的dosomething聲明:

class dosomething:public

std::binary_funcation

{

//其中,int是我們當前iterator值類型,const char *是要傳遞的固定不變的字元串,void是我們func的傳回值。看看下面的重載() 聲明,就明白了:

public:

void operator()(int ival, const char *s)

{

// 在這裡添加你想幹的事情,記住,ival就是當前iterator的值, s是需要綁定的不變字元串

}

};

3、bind1st和bind2nd的選擇

從如上的dosomething可以看出,需要綁定的是s這個不變字元串,是第二個參數,是以當然選擇bind2nd,如果dosomething的聲明如下:

class dosomething:public

std::binary_funcation

{

//其中,int是我們當前iterator值類型,const char *是要傳遞的固定不變的字元串,void是我們func的傳回值。看看下面的重載() 聲明,就明白了:

public:

void operator()(const char *s, int)

{

// 在這裡添加你想幹的事情,記住,ival就是當前iterator的值, s是需要綁定的不變字元串

}

};

那麼就當然選擇bind1st了,因為需要綁定的不變參數s是第一個參數。

我靠,原來這兩個函數沒什麼本質區別,隻是根據用戶定義函數參數的順序有關。

4、現在看看改進後的程式:

#include

#include

#include

#include

#include

void doSomething(const char *c, int i);

// 我的第一個二進制功能函數,

// 首先,我假定doSomething是某個庫函數,

// 我並沒有它的源代碼。

// 關於可移植性:MS VC6.0不喜歡在模闆的傳回類型中使用void,

// 是以在MS VC6.0中對operator( )稍作修改,使它傳回一個類型(如true)

struct doSomethingWrapper : public

std::binary_function

{

// 實際上iValue就是iteraor的derefence值, cValue是不變的捆綁值

void operator()(const char *cValue, int iValue) const

{

doSomething(cValue, iValue);

}

};

// 現在,就建立了一個內部的功能函數。

// 關於可移植性,同上。

struct doSomethingDirect : public

std::binary_function

{

void operator()(const char *cValue, int iValue) const

{

std::cout << cValue

<< " "

<< iValue

<< ". " << std::endl;

}

};

// 這是個幫助器模闆,因為我比較懶,它能減少打字量。

template

Function for_all(Collection &c, const Function &f)

{

return std::for_each(c.begin(), c.end(), f);

}

int main()

{

// 首先,建立vector。

std::vector vect;

for (int i=1; i<10; ++i) {

vect.push_back(i);

}

for_all(vect, std::bind1st(doSomethingWrapper(), "Wrapper:"));

std::cout << "/n";

for_all(vect, std::bind1st(doSomethingDirect(), "Direct:"));

getchar();

return 0;

}

// 我獨樹一幟的第三方庫函數

void doSomething(const char *c, int i)

{

std::cout << c << " " << i << ". " << std::endl;

}

5、問題思考,如果用bind2nd怎樣實現?自己去想吧!然後對容器的erase的操作就可以用它來實現了

備註:部分測試程式來源於csdn,請原諒我的部分改動!