策略類模板
在前面的博文中,策略類SumPolicy
和MinPolicy
都是普通的類,其中包含的是一個靜態成員函數模板algorithm()
,該函數模板包含兩個類型模板參數。其實,也可以把SumPolicy
和MinPolicy類
寫成類模板—直接把algorithm()
中的兩個類型模板參數搬到類定義上面作為類模板的模板參數就可以了。類模板SumPolicy
和MinPolicy
的實現代碼如下。
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()
函數模板,該函數模板的第3個類型模板參數要作出改變,當前第3個類型模板參數的默認值是SumPolicy
,這是一個類型,但是,修改后的SumPolicy
已經是一個類模板了,所以funcsum()
函數模板的第3個模板參數必須是一個模板模板參數。修改后的funcsum()
函數模板如下。
// 這里的class也可以寫成typename
template<typename T,typename U = SumFixedTraits<T>,template<class,class> class V = SumPolicy>
auto funcsum(const T* begin, const T* end)
{typename U::sumT sum = U::initValue();for (;;){V<U::sumT, T>::algorithm(sum, *begin);// T時數組成員類型,U是固定萃取類模板,從中可以提取出計算的結果類型(U::sumT)// 以及結果的初值,V是策略類模板,用于實現具體算法(求和,求最小值等)if (begin == end)break;++begin;}return sum;
}
完整且完美的代碼,如下:
#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;}
};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;}
};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;}
};// 這里的class也可以寫成typename
template<typename T,typename U = SumFixedTraits<T>,template<class,class> class V = SumPolicy>
auto funcsum(const T* begin, const T* end)
{typename U::sumT sum = U::initValue();for (;;){V<typename U::sumT, T>::algorithm(sum, *begin);// T時數組成員類型,U是固定萃取類模板,從中可以提取出計算的結果類型(U::sumT)// 以及結果的初值,V是策略類模板,用于實現具體算法(求和,求最小值等)if (begin == end)break;++begin;}return sum;
}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;
}
萃取技術與策略技術的比較
- 之前的博文,學習了
萃取(trait)技術
,也學習了策略(policy)技術
,對于萃取技術,通過范例展示了固定萃取和值萃取;對于策略技術,展示了算法策略。萃取技術和策略技術很相似,注意它們之間的相同與不同之處。
- (1)兩種技術都像一個中間件一樣,夾在不同的功能代碼之間,使代碼之間的調用(交互)更加靈活。
- (2)萃取技術傳入一個類型,萃取出另外一個類型或值(注重類型或值);而策略技術是傳入一個類型,萃取出一個算法,或者說是一個不同的功能實現(注重動作或行為)。因此,書寫策略類(類模板)時通常都需要包含成員函數以實現指定的行為。但在實際的項目實現中,也可能會在萃取類中實現某些動作或行為,從這個角度來講,兩種技術有時區分并不是那么明顯。
- (3)萃取技術一般通過一個類模板來實現,通常包含類模板的泛化版本和多個特化版本。而策略技術用普通類或類模板都可以實現。