Traits and policy are quite common in generic programming. Like the STL string implementation inside the Traits,boost used in a lot of places to use traits.
Traits and policy are often used together, allowing us to have some more ideas in generic programming.
Traits: Chinese interpretation as a feature, remember that in the "STL Source Analysis," The book is also called the extraction of something. When we want to get an additional feature from a type, we can often consider traits. For example, having a type T, doing something to him, and then returning a type, it can be understood that a return type is related to T. And, for example, given an iterator, want to get the relevant container type from the iterator. This is a typical application of type traits, as for value traits, a lot of the time is to append an initialization value to the type in a traits. You can often see a tratis class that has a type definition and a corresponding initialization (a static constant or a static function). Similar:
Template<>struct traits<int>{typedef Double accut;static accut Zero () {return 0.0;};};
Policy: Chinese is interpreted as a strategy. In generic programming, policy can often be used if certain behavior codes may change. You can change the behavior of a template function by using different policy. For example, the following code:
Template<class T, class P>typename traits<t>::accut accum (const t* ptr, int len) {traits<t>::accut Total = Traits<t>::zero (); for (int i = 0; i < len; i++) {p::accumulate (total, * (ptr + i));} return total;}
If the additive algorithm may change, then we can implement different algorithms by passing in a template class through the member functions of this class.
Traits and policy broaden our horizons, giving us some more ideas. But do not blindly abuse (like design patterns, sometimes over-design is better than no design).
STL's accumulate function does not use traits and policy. Look at the following code:
Template<class _init,class _ty> inline_ty accumulate (_init _first, _init _last, _Ty _Val) {//return sum of _Val and All in [_first, _last] _debug_range (_first, _last); return (_accumulate (_unchecked (_first), _unchecked (_last), _Val));}
Template<class _init,class _ty,class _fn2> inline_ty accumulate (_init _first, _InIt _Last, _Ty _Val, _Fn2 _Func) {// Return sum of _val and all in [_first, _last), using _func_debug_range (_first, _last); _debug_pointer (_func); return (_accum Ulate (_unchecked (_first), _unchecked (_last), _val, _func));}
The return value type of std::accumulate () is actually a _ty _val passed in through a template parameter. The behavior function is also a _fn2 _func that is worn through a template parameter.
Personally feel that each solution has its own pros and cons, or that sentence, to use the right solution for the right occasion. The solution itself is not absolutely good and bad, only the right solution does not have the best solution (only the strongest player does not have the strongest job)
Traits's original author Nathan has a saying: traits is a scheme that replaces template parameters. However, he did not say that the template parameters are not good, or traits than the template parameter is much better.
C + + templates-traits & Policy