策略技術中的算法策略
- 在之前博客中
funcsum()函數模板
中,實現了對數組元素的求和運算。求和在這里可以看作一種算法,擴展一下思路,對數組元素求差、求乘積、求最大值和最小值等,都可以看作算法。 - 而當前的
funcsum()函數模板
中,已經將數組元素的求和算法固定寫在了程序代碼中,為了靈活地將求和算法調整為求乘積、求最大值等算法,可以通過引入一個策略(policy)類SumPolicy
達到目的。
// 求和策略類以實現求和算法
struct SumPolicy
{// 靜態成員函數模板template<typename sumT,typename T> // sumT是和值類型,T是數組元素類型static void algorithm(sumT& sum, const T& value) // 該策略類的核心算法{sum += value;}
};
接著,為funcsum()函數模板
增加一個新的類型模板參數,這個模板參數的默認值就是這個策略類。
修改funcsum()函數模板
:
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 (;;){// sum += (*begin); 此行被下面一行取代V::algorithm(sum, *begin);if (begin == end)break;++begin;}return sum;
}
如果要計算一個整型數組中元素的最小值,如何實現?第1件想到的事情就是寫一個新的策略類,如這里寫一個MinPolicy類
(仿照SumPolicy類
的寫法)。
struct MinPolicy
{template<typename minT,typename T>static void algorithm(minT& min, const T& value){if (min > value)min = value;}
};
在main()
主函數中重新寫入代碼:
#include "killCmake.h"#include<string>using namespace std;template<typename T>
struct SumFixedTraits;template<>
struct SumFixedTraits<char>
{using sumT = int;static sumT initValue() {return 0;}
};// 最求值策略技術時,為了求最小值,初始化需要很大
// 所以初始值可以為int最大值21億
template<>
struct SumFixedTraits<int>
{using sumT = __int64;static sumT initValue() {return 2100000000;}
};template<>
struct SumFixedTraits<double>
{using sumT = double;static sumT initValue() {return 0.0;}
};template<typename T,typename U = SumFixedTraits<T>>
auto funcsum(const T* begin, const T* end)
{// using sumT = typename SumFixedTraits<T>::sumT; 本行不需要// sumT sum = SumFixedTraits<T>::initValue(); 本行不需要typename U::sumT sum = U::initValue();for (;;){sum += (*begin);if (begin == end)break;++begin;}return sum;
}// 求和策略類以實現求和算法
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 (;;){// sum += (*begin); 此行被下面一行取代V::algorithm(sum, *begin);if (begin == end)break;++begin;}return sum;
}struct MinPolicy
{template<typename minT,typename T>static void algorithm(minT& min, const T& value){if (min > value)min = value;}
};int main()
{//char my_char_array[] = "abc";//std::cout << (int)(funcsum(&my_char_array[0], &my_char_array[2])) << std::endl;//std::cout << (int)(funcsum<char, SumFixedTraits<int>>(&my_char_array[0], &my_char_array[2])) << std::endl;int my_int_array1[] = { 10,15,20 };std::cout << funcsum<int, SumFixedTraits<int>, MinPolicy>(&my_int_array1[0], &my_int_array1[2]) << std::endl;return 0;
}
這個程序真的很經典,個人覺得,應該屬于中上乘武功了
- 運行程序,看一看新增的代碼結果是否正確,最開始發現結果為0,顯然這個結果是不正確的。究其原因,在
funcsum()
中,sum
(用于保存數組元素最小值的變量)的初值被設置為0。如果是計算數組元素和值,則sum
的初值被設置為0是很正常的;但如果要計算數組元素的最小值,則把sum
的初值設置為0是不正常的(因為數組中元素的最小值也很可能比0大,有這個0存在,就無法找到數組中元素的真正最小值)。 - 解決方案有以下兩個。
- (1)可以給
funcsum()函數模板
增加一個非類型模板參數,用于把初值傳遞進來。 - (2)也可以重新寫一個固定萃取類模板取代當前的
SumFixedTraits模板
。這里采用后一種解決方案,書寫一個新的固定萃取類模板,取名為MinFixedTraits
。
#include "killCmake.h"#include<string>using namespace std;template<typename T>
struct SumFixedTraits;template<>
struct SumFixedTraits<char>
{using sumT = int;static sumT initValue() {return 0;}
};// 最求值策略技術時,為了求最小值,初始化需要很大
// 所以初始值可以為int最大值21億
template<>
struct SumFixedTraits<int>
{using sumT = __int64;static sumT initValue() {return 2100000000;}
};template<>
struct SumFixedTraits<double>
{using sumT = double;static sumT initValue() {return 0.0;}
};template<typename T>
struct MinFixedTraits;template<>
struct MinFixedTraits<int>
{// 求最小值,結果類型與元素類型相同即可// 為名字統一,都用sumT這個名字using sumT = int;static sumT initValue(){// 這里給整型最大值,相信任何一個數組元素都不會比這個值更大// 因此可以順利找到數組元素中的最小值return INT_MAX;}
};// 求和策略類以實現求和算法
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 (;;){// sum += (*begin); 此行被下面一行取代V::algorithm(sum, *begin);if (begin == end)break;++begin;}return sum;
}struct MinPolicy
{template<typename minT,typename T>static void algorithm(minT& min, const T& value){if (min > value)min = value;}
};int main()
{int my_int_array1[] = { 10,15,20 };std::cout << funcsum<int, MinFixedTraits<int>, MinPolicy>(& my_int_array1[0], & my_int_array1[2]) << std::endl;return 0;
}
運行程序,新增的代碼行結果為10,一切正常。