Advertisement
Guest User

templates

a guest
Oct 5th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <type_traits>
  4.  
  5. /* примеры реализации стандартных классов типов */
  6. template<bool Condition, typename T = void>
  7. struct enable_if {};
  8.  
  9. template<typename T>
  10. struct enable_if<true, T> {
  11.     typedef T type;
  12. };
  13.  
  14. template<typename T> struct is_integral {
  15.     static const bool value = false;
  16. };
  17.  
  18. template<> struct is_integral<int> {
  19.     static const bool value = true;
  20. };
  21. // и так далее для всех интегральных типов
  22.  
  23. /* общий шаблон для классов-итераторов, унаследованных от std::iterator */
  24. template<typename Iterator>
  25. struct iterator_traits {
  26.     typedef typename Iterator::value_type value_type;
  27.     typedef typename Iterator::pointer pointer;
  28.     // и так далее
  29. };
  30.  
  31. /* специализируем для указателей */
  32. template<typename T>
  33. struct iterator_traits<T*> {
  34.     typedef T value_type;
  35.     typedef T *pointer;
  36.     // ...
  37. };
  38.  
  39.  
  40. template<typename T>
  41. class Array {
  42. public:
  43.     Array(size_t n, const T& val): data_(n, val) {
  44.         std::cout << "1\n";
  45.     }
  46.  
  47.     /* sfinae */
  48.     /* правильно конечно использовать список инициализации,
  49.      * напишем так, чтобы явно видеть CE без sfinae */
  50.     template<
  51.         typename Iterator,
  52.         typename = typename std::enable_if<!std::is_integral<Iterator>::value>::type
  53.     >
  54.     Array(Iterator first, Iterator last) {
  55.         while (first != last)
  56.             data_.push_back(*first++);
  57.         std::cout << "2\n";
  58.     }
  59. private:
  60.     std::vector<T> data_;
  61. };
  62.  
  63. /* еще одно применение шаблонов - используем механизм подстановки
  64.  * чтобы узнать размер массива на этапе компиляции */
  65. template<typename T, size_t N>
  66. size_t size(T (&array)[N]) {
  67.     return N;
  68. }
  69.  
  70. template<typename Iterator>
  71. void print(Iterator first, Iterator last) {
  72.     while (first != last) {
  73.         /* имя типа зависит от параметра шаблона, необходимо typename
  74.          * явно определяем тип с помощью iterator_traits */
  75.         typename iterator_traits<Iterator>::value_type cur_element = *first;
  76.         std::cout << cur_element << " ";
  77.         ++first;
  78.     }
  79.     std::cout << "\n";
  80. }
  81.  
  82. int main() {
  83.     std::vector<int> v{1, 2, 3};
  84.     Array<int> a(5, 3); // CE если не использовать sfinae
  85.     Array<int> b(v.begin(), v.end());
  86.  
  87.     int c[3] = {2, 3, 4};
  88.     std::cout << size(c) << "\n";
  89.  
  90.     print(v.begin(), v.end()); // Iterator = std::vector<int>::iterator
  91.     print(c, c + 3); // Iterator = int *
  92.     return 0;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement