国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】STL 算法 ③ ( 函數(shù)對(duì)象中存儲(chǔ)狀態(tài) | 函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題 | for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞 )

這篇具有很好參考價(jià)值的文章主要介紹了【C++】STL 算法 ③ ( 函數(shù)對(duì)象中存儲(chǔ)狀態(tài) | 函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題 | for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞 )。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。





一、函數(shù)對(duì)象中存儲(chǔ)狀態(tài)



1、函數(shù)對(duì)象中存儲(chǔ)狀態(tài)簡(jiǎn)介


在 C++ 語(yǔ)言中 , 函數(shù)對(duì)象 / 仿函數(shù) 可以像函數(shù)一樣被調(diào)用 , 并且 其 還具有類的特征 , 可以 通過(guò) 繼承 和 重載 來(lái) 修改 重載函數(shù)調(diào)用操作符函數(shù) 的行為 ;

函數(shù)對(duì)象 / 仿函數(shù) 通常是通過(guò) 定義一個(gè)類 , 然后為這個(gè)類 重載 函數(shù)調(diào)用操作符 () 來(lái)實(shí)現(xiàn)的 ;

函數(shù)對(duì)象的一個(gè)重要特性是 " 可以存儲(chǔ)狀態(tài) " ; 這意味著你可以 在類的成員變量中存儲(chǔ)數(shù)據(jù) , 這些數(shù)據(jù)可以 在函數(shù)調(diào)用之間保持不變 ;

普通的函數(shù) 是 無(wú)法存儲(chǔ)狀態(tài) 的 , 因?yàn)?普通函數(shù) 中 局部變量 在函數(shù)執(zhí)行完成后 , 自動(dòng)銷毀 ;


函數(shù)對(duì)象 / 仿函數(shù) 的一個(gè)主要優(yōu)勢(shì)是它們可以擁有狀態(tài) , 而普通函數(shù)則不能 ;

這使得 " 函數(shù)對(duì)象 / 仿函數(shù) " 在需要保持 某些數(shù)據(jù)或狀態(tài) 在 多次函數(shù)調(diào)用 之間不變的情況下非常有用 ,

例如 : 在 STL 算法中 , 函數(shù)對(duì)象經(jīng)常被用作 謂詞 或 用于在容器的每個(gè)元素上執(zhí)行某種操作的函數(shù) , 由于它們可以存儲(chǔ)狀態(tài) , 因此可以根據(jù)算法的需要進(jìn)行定制 ;

在下面的示例中 , 函數(shù)對(duì)象 中 維護(hù)了一個(gè)狀態(tài)位 , 用于記錄該 函數(shù)對(duì)象 的調(diào)用次數(shù) ;


下面的 函數(shù)對(duì)象 / 仿函數(shù) 中 , 存儲(chǔ)了狀態(tài) n , 每調(diào)用一次該仿函數(shù) , 該成員自增 1 ;

//函數(shù)對(duì)象 類重載了()
template <typename T>
class PrintT {
public:
	void operator()(T& t) {
		cout << n << " . " << t << endl;
		// 每調(diào)用一次, 自增 1
		n++;
	}

private:
	// 每調(diào)用一次, 該成員自增 1
	// 該狀態(tài)一直存儲(chǔ)
	int n = 0;
};

2、示例分析


在下面的代碼示例中 ,

首先 , 定義了 函數(shù)對(duì)象 / 仿函數(shù) PrintT 類 , 該類 重載了 函數(shù)調(diào)用操作符 () , 其重載函數(shù)是 void operator()(T& t) ;

  • 在該 函數(shù)對(duì)象 中 , 存儲(chǔ)了一個(gè)狀態(tài)值 n ,
  • 每次調(diào)用該 重載函數(shù) , 狀態(tài)值 n 都會(huì)自增 1 ;
//函數(shù)對(duì)象 類重載了()
template <typename T>
class PrintT {
public:
	void operator()(T& t) {
		cout << n << " . " << t << endl;
		// 每調(diào)用一次, 自增 1
		n++;
	}

private:
	// 每調(diào)用一次, 該成員自增 1
	// 該狀態(tài)一直存儲(chǔ)
	int n = 0;
};

然后 , 在 foreach 循環(huán)中 , 將該 函數(shù)對(duì)象 傳入 循環(huán)算法 中 , 每次遍歷 vector 容器中的元素時(shí) , 都會(huì)調(diào)用 該 函數(shù)對(duì)象 , 同時(shí) 每次調(diào)用 時(shí) , 函數(shù)對(duì)象中的 n 值都會(huì)自增 1 ;

	// 向 foreach 循環(huán)中傳入函數(shù)對(duì)象
	// 在函數(shù)對(duì)象中打印元素內(nèi)容
	for_each(vec.begin(), vec.end(), PrintT<int>());

代碼示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

//函數(shù)對(duì)象 類重載了()
template <typename T>
class PrintT {
public:
	void operator()(T& t) {
		cout << n << " . " << t << endl;
		// 每調(diào)用一次, 自增 1
		n++;
	}

private:
	// 每調(diào)用一次, 該成員自增 1
	// 該狀態(tài)一直存儲(chǔ)
	int n = 0;
};

int main() {

	// 創(chuàng)建一個(gè) vector 單端數(shù)組容器
	vector<int> vec;

	// 向容器中插入元素
	vec.push_back(1);
	vec.push_back(3);
	vec.push_back(5);

	// 向 foreach 循環(huán)中傳入函數(shù)對(duì)象
	// 在函數(shù)對(duì)象中打印元素內(nèi)容
	for_each(vec.begin(), vec.end(), PrintT<int>());


	// 控制臺(tái)暫停 , 按任意鍵繼續(xù)向后執(zhí)行
	system("pause");
	return 0;
};

執(zhí)行結(jié)果 : 打印時(shí) , 先把狀態(tài)值 n 打印出來(lái) , 然后跟著打印 vector 容器中的元素 ,

0 . 1
1 . 3
2 . 5
請(qǐng)按任意鍵繼續(xù). . .

【C++】STL 算法 ③ ( 函數(shù)對(duì)象中存儲(chǔ)狀態(tài) | 函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題 | for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞 ),C++,c++,開發(fā)語(yǔ)言,STL,函數(shù)對(duì)象,仿函數(shù),值傳遞,引用傳遞





二、函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題



1、for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞


下面開始分析 for_each 函數(shù)中 函數(shù)對(duì)象 作為參數(shù)的 具體細(xì)節(jié) ;

for_each 算法的調(diào)用代碼如下 :

	// 向 foreach 循環(huán)中傳入函數(shù)對(duì)象
	// 在函數(shù)對(duì)象中打印元素內(nèi)容
	for_each(vec.begin(), vec.end(), PrintT<int>());

for_each 算法的函數(shù)原型如下 :

// FUNCTION TEMPLATE for_each
template <class _InIt, class _Fn>
_Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last)
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        _Func(*_UFirst);
    }

    return _Func;
}

上述 for_each 函數(shù)的 形參 _Fn _Func 是一個(gè) 值 , 不是引用 ;

傳遞的是 引用 的話 , 那么 外部的對(duì)象 和 實(shí)參值 是相同的對(duì)象 ;

傳遞的是 值 的話 , 那么 實(shí)參 只是 外部的對(duì)象 的 副本值 , 在 for_each 函數(shù)中 , 無(wú)論如何操作改變實(shí)參 , 都不會(huì)影響到 外部的對(duì)象 ;


如果 在 for_each 算法中 調(diào)用了 函數(shù)對(duì)象 , 函數(shù)對(duì)象中 有 狀態(tài)改變 ;

在 for_each 算法 外部 繼續(xù)調(diào)用該 函數(shù)對(duì)象 , 由于 for_each 是 值傳遞 , 傳遞的 只是 函數(shù)對(duì)象副本 , 副本的 狀態(tài)改變 不會(huì)影響到外部函數(shù) ;

如果想要 保留上述 狀態(tài)改變 , 則需要使用 函數(shù)對(duì)象 接收 for_each 的返回值 , 這個(gè)函數(shù)對(duì)象 保留了 內(nèi)部 函數(shù)對(duì)象參數(shù)副本 的狀態(tài)值 ;


2、代碼示例 - for_each 函數(shù)的 函數(shù)對(duì)象 參數(shù)在外部不保留狀態(tài)


如果 在 for_each 算法中 調(diào)用了 函數(shù)對(duì)象 , 函數(shù)對(duì)象中 有 狀態(tài)改變 ;

在 for_each 算法 外部 繼續(xù)調(diào)用該 函數(shù)對(duì)象 , 由于 for_each 是 值傳遞 , 傳遞的 只是 函數(shù)對(duì)象副本 , 副本的 狀態(tài)改變 不會(huì)影響到外部函數(shù) ;


在外部調(diào)用 函數(shù)對(duì)象 時(shí) , 發(fā)現(xiàn)狀態(tài)值 還是 0 , 這說(shuō)明 值傳遞 改變的是 函數(shù)對(duì)象實(shí)參副本值 , 沒有影響外部的 函數(shù)對(duì)象 值 ;

0 . 666

代碼示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

//函數(shù)對(duì)象 類重載了()
template <typename T>
class PrintT {
public:
	void operator()(T& t) {
		cout << n << " . " << t << endl;
		// 每調(diào)用一次, 自增 1
		n++;
	}

private:
	// 每調(diào)用一次, 該成員自增 1
	// 該狀態(tài)一直存儲(chǔ)
	int n = 0;
};

int main() {

	// 創(chuàng)建一個(gè) vector 單端數(shù)組容器
	vector<int> vec;

	// 向容器中插入元素
	vec.push_back(1);
	vec.push_back(3);
	vec.push_back(5);


	// 創(chuàng)建函數(shù)對(duì)象
	PrintT<int> printT;

	// 向 foreach 循環(huán)中傳入函數(shù)對(duì)象
	// 在函數(shù)對(duì)象中打印元素內(nèi)容
	for_each(vec.begin(), vec.end(), printT);

	// 再次調(diào)用 函數(shù)對(duì)象
	cout << "再次調(diào)用函數(shù)對(duì)象 : " << endl;
	int a = 666;
	printT(a);


	// 控制臺(tái)暫停 , 按任意鍵繼續(xù)向后執(zhí)行
	system("pause");
	return 0;
};

執(zhí)行結(jié)果 :

0 . 1
1 . 3
2 . 5
再次調(diào)用函數(shù)對(duì)象 :
0 . 666
請(qǐng)按任意鍵繼續(xù). . .

【C++】STL 算法 ③ ( 函數(shù)對(duì)象中存儲(chǔ)狀態(tài) | 函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題 | for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞 ),C++,c++,開發(fā)語(yǔ)言,STL,函數(shù)對(duì)象,仿函數(shù),值傳遞,引用傳遞


3、代碼示例 - for_each 函數(shù)的 函數(shù)對(duì)象 返回值


如果 在 for_each 算法中 調(diào)用了 函數(shù)對(duì)象 , 函數(shù)對(duì)象中 有 狀態(tài)改變 ;

在 for_each 算法 外部 繼續(xù)調(diào)用該 函數(shù)對(duì)象 , 由于 for_each 是 值傳遞 , 傳遞的 只是 函數(shù)對(duì)象副本 , 副本的 狀態(tài)改變 不會(huì)影響到外部函數(shù) ;

如果想要 保留上述 狀態(tài)改變 , 則需要使用 函數(shù)對(duì)象 接收 for_each 的返回值 , 這個(gè)函數(shù)對(duì)象 保留了 內(nèi)部 函數(shù)對(duì)象參數(shù)副本 的狀態(tài)值 ;


使用 PrintT<int> printT; 函數(shù)對(duì)象 變量 , 接收 for_each 算法的返回值 , 再次執(zhí)行該 函數(shù)對(duì)象 調(diào)用 , 發(fā)現(xiàn) 狀態(tài)值被保留了下來(lái) , 打印值為 :

3 . 666

代碼示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

//函數(shù)對(duì)象 類重載了()
template <typename T>
class PrintT {
public:
	void operator()(T& t) {
		cout << n << " . " << t << endl;
		// 每調(diào)用一次, 自增 1
		n++;
	}

private:
	// 每調(diào)用一次, 該成員自增 1
	// 該狀態(tài)一直存儲(chǔ)
	int n = 0;
};

int main() {

	// 創(chuàng)建一個(gè) vector 單端數(shù)組容器
	vector<int> vec;

	// 向容器中插入元素
	vec.push_back(1);
	vec.push_back(3);
	vec.push_back(5);


	// 創(chuàng)建函數(shù)對(duì)象
	PrintT<int> printT;

	// 向 foreach 循環(huán)中傳入函數(shù)對(duì)象
	// 在函數(shù)對(duì)象中打印元素內(nèi)容
	printT = for_each(vec.begin(), vec.end(), printT);

	// 再次調(diào)用 函數(shù)對(duì)象
	cout << "再次調(diào)用函數(shù)對(duì)象 : " << endl;
	int a = 666;
	printT(a);


	// 控制臺(tái)暫停 , 按任意鍵繼續(xù)向后執(zhí)行
	system("pause");
	return 0;
};

執(zhí)行結(jié)果 :

0 . 1
1 . 3
2 . 5
再次調(diào)用函數(shù)對(duì)象 :
3 . 666
請(qǐng)按任意鍵繼續(xù). . .

【C++】STL 算法 ③ ( 函數(shù)對(duì)象中存儲(chǔ)狀態(tài) | 函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題 | for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞 ),C++,c++,開發(fā)語(yǔ)言,STL,函數(shù)對(duì)象,仿函數(shù),值傳遞,引用傳遞文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-788503.html

到了這里,關(guān)于【C++】STL 算法 ③ ( 函數(shù)對(duì)象中存儲(chǔ)狀態(tài) | 函數(shù)對(duì)象作為參數(shù)傳遞時(shí)值傳遞問題 | for_each 算法的 函數(shù)對(duì)象 參數(shù)是值傳遞 )的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包