As reading the C++ template metaprogramming, I learn the famous saying in software engineering again. How to understand this remark in the context of C++ template metaprogramming?
What we have to mention is the type trait skill, I‘d like to reference the demo in the book:
template <class ForwardIterator1, class ForwardIterator2> void iter_swap(ForwardIterator1 i1, ForwardIterator2 i2) { typename // (see Language Note) ForwardIterator1::value_type tmp = *i1; *i1 = *i2; *i2 = tmp; }
We can make this function work only if the template parameter ForwardIterator1 has a "Property" named as value type; What if we assign a plain int* to ForwardIterator1?The compiler will complain there is no value_type defined in int*. But int* is exactly an iterable type, we have to fix this problem. The mean we introduce is to setup an extra level of indirection. The extra level of indirection is the trait:
template <class Iterator> struct iterator_traits { typedef typename Iterator::value_type value_type; ...four more typedefs };
Then we can use this level of indirection to be a adapter for the typing difference;
template <class ForwardIterator1, class ForwardIterator2> void iter_swap(ForwardIterator1 i1, ForwardIterator2 i2) { typename iterator_traits<ForwardIterator1>::value_type tmp = *i1; *i1 = *i2; *i2 = tmp; }
In case of int*, we use partial specialization syntax of C++
template <> struct iterator_traits<T*> { typedef T value_type; four more typedefs... };
The compiler will not complain because of the existance of the extra level of indirection: traits
Traits achieve the type recognization non-intrusively, "the generic function can access the type uniformly";
时间: 2024-10-24 19:03:34