(C++模板程式設計):策略(policy)技術中的演算法策略與總結

Asinmy發表於2020-11-18

目錄

策略(policy)技術中的演算法策略

常規範例:普通策略類

常規範例:策略類别範本

【總結】萃取(trait)技術與策略(policy)技術的思想

策略(policy)技術中的演算法策略

  • 演算法邏輯分離,解耦合

常規範例:普通策略類

【引例】

//funcsum函式模板
template <typename T,typename U = SumFixedTraits<T> > 
auto funcsum(const T* begin, const T* end)
{
	typename U::sumT sum = U::initValue();  
 
	for (;;)
	{
		sum += (*begin);
		if (begin == end)
			break;
		++begin;
	}//end for
	return sum;
}
  • 這是前面的案例,其中可以把funcsum求和看成是一種演算法,但是這樣就只能求和,若是要求乘除等就得重新寫。

【使用策略】

//求和策略類以實現求和演算法。
struct SumPolicy
{
	//靜態成員函式模板
    template <typename sumT, typename T> //sumT是和值型別,T是陣列元素型別
	static void algorithm(sumT& sum, const T& value) //策略類的核心演算法
	{
		sum += value; //求和
	}
};

template <typename T, typename U = SumFixedTraits<T> ,typename V = SumPolicy>
auto funcsum(const T* begin, const T* end)
{
    typename U::sumT sum = U::initValue();
    for (;;)
    {
	    V::algorithm(sum, *begin);
	    if (begin == end)
		    break;
		++begin;
	    }//end for
	return sum;
}
  • 呼叫
char mychararray[] = "abc";
cout << (int)(funcsum(&mychararray[0], &mychararray[2])) << endl;

【最小值策略】

template <typename T>
struct MinFixedTraits;

template<>
struct MinFixedTraits<int>
{
	using sumT = int; //求最小值,結果型別與元素型別相同即可,為了名字統一,都用sumT這個名字
	static sumT initValue() { return INT_MAX; } 
    //INT_MAX:整型最大值,任何一個陣列元素都不會被這個值更大
    //因此可以順利的找到陣列元素中的最小值,參見MinPolicy::algorithm
};


//求最小值策略類
struct MinPolicy
{
    template <typename minT, typename T>
	static void algorithm(minT& min, const T& value)
	{
		if (min > value)
			min = value;
	}
};
  • 呼叫
int myintarray1[] = { 10,15,20 };
cout << (int)(funcsum<int, MinFixedTraits<int>, MinPolicy>(&myintarray1[0], &myintarray1[2])) << endl;

常規範例:策略類别範本

  • 上面的類通過在普通類中使用靜態成員函式模板實現策略。
  • 下面將普通類改成類别範本。
//求和策略類以實現求和演算法。
template <typename sumT, typename T>
struct SumPolicy
{
	//靜態成員函式模板
	static void algorithm(sumT& sum, const T& value) //策略類的核心演算法
	{
		sum += value; //求和
	}
};

//求最小值策略類
template <typename minT, typename T>
struct MinPolicy
{
	static void algorithm(minT& min, const T& value)
	{
		if (min > value)
			min = value;
	}
};
//funcsum函式模板
template <typename T, 
			typename U = SumFixedTraits<T> ,
			template<class,class> class V = SumPolicy //這裡class也可以寫成typename
>
auto funcsum(const T* begin, const T* end)
{
	typename U::sumT sum = U::initValue();  //typename SumFixedTraits<char>::sumT sum = SumFixedTraits<char>::initValue();
											 //int sum = 0;

	for (;;)
	{
		V<U::sumT,T>::algorithm(sum, *begin); //捋一下:T是陣列成員型別,U是固定萃取(fixed traits)類别範本,
		                                      //從中可以提取出結算的結果型別(U::sumT)以及結果的初值,
		                                      //V是策略類别範本,用於實現具體演算法(求和,求最小值等)

		if (begin == end)
			break;
		++begin;
	}//end for
	return sum;
}
  • 呼叫
int myintarray1[] = { 10,15,20 };
cout << (int)(funcsum<int, MinFixedTraits<int>, MinPolicy>(&myintarray1[0], &myintarray1[2])) << endl;

【總結】萃取(trait)技術與策略(policy)技術的思想

  • 兩種技術都象一箇中介軟體一樣,夾在不同的功能程式碼之間,讓程式碼之間的呼叫更加靈活。
  • 萃取技術:給進去一個型別,萃取出另外一個型別或者另外一個值(注重於型別或者指定)
  • 策略技術:給進去一個型別,萃取出一個演算法或者是一個不同的功能實現(注重於動作或者行為)
    • 因此,在書寫策略類(類别範本)的時候通常都需要包含(靜態)成員函式以實現指定的行為
  • 有時,萃取技術中也可能實現某些動作或者行為,所以從這個角度來講,萃取技術與策略技術有時區分不是那麼明顯
  • 萃取技術一般通過一個類别範本來實現,通常包含類别範本的泛化版本和多個特化版本。
  • 策略技術用普通類或者類别範本都可以實現。

相關文章