Guest User

Untitled

a guest
Nov 18th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.10 KB | None | 0 0
  1. // Tag dispatching is used to select the correct overload for a function based on type traits.
  2. // A common example uses iterators to illustrate the concept.
  3.  
  4. #include <iterator>
  5. #include <vector>
  6. #include <list>
  7.  
  8. template<typename Iterator>
  9. void advance(Iterator& iterator, intptr_t distance, std::forward_iterator_tag)
  10. {
  11. printf("I'm advancing a forward iterator.\n");
  12. iterator ++;
  13. }
  14.  
  15. template<typename Iterator>
  16. void advance(Iterator& iterator, intptr_t distance, std::random_access_iterator_tag)
  17. {
  18. printf("I'm advancing a random access iterator.\n");
  19. iterator += distance;
  20. }
  21.  
  22. template<typename Iterator>
  23. void advance(Iterator& iterator, intptr_t distance, std::bidirectional_iterator_tag)
  24. {
  25. printf("I'm advancing a bidirectional iterator.\n");
  26.  
  27. if (distance < 0)
  28. {
  29. while (distance)
  30. {
  31. iterator--;
  32. distance++;
  33. }
  34. }
  35. else if (distance > 0)
  36. {
  37. while (distance)
  38. {
  39. iterator++;
  40. distance--;
  41. }
  42. }
  43. }
  44.  
  45. // Catch anything else here.
  46. template<typename Iterator, typename T>
  47. void advance(Iterator& iterator, intptr_t distance, T)
  48. {
  49. static_assert(0, "I don't know how to move this type of iterator.\n");
  50. }
  51.  
  52. template<typename T>
  53. void advance(T& iterator, intptr_t distance)
  54. {
  55. advance(iterator, distance, T::iterator_category{});
  56. }
  57.  
  58. template<typename T>
  59. struct my_forward_iterator
  60. {
  61. using iterator_category = std::forward_iterator_tag;
  62. void operator++(int) { /*Do nothing*/ }
  63. };
  64.  
  65. template<typename T>
  66. struct my_unsupported_iterator
  67. {
  68. using iterator_category = std::output_iterator_tag;
  69. };
  70.  
  71. int main(size_t argc, char** argv)
  72. {
  73. std::vector<int> my_vector { 1, 2, 3, 4, 5 };
  74. std::list<int> my_list { 1, 2, 3, 4, 5 };
  75.  
  76. advance(my_vector.begin(), 3);
  77. advance(my_list.begin(), 3);
  78. advance(my_forward_iterator<int>(), 3);
  79.  
  80. // Enabling this will cause the static assert to fire.
  81. // advance(my_unsupported_iterator<int>(), 3);
  82.  
  83. // EXPECTED OUTPUT:
  84. // I'm advancing a random access iterator.
  85. // I'm advancing a bidirectional iterator.
  86. // I'm advancing a forward iterator.
  87. }
Add Comment
Please, Sign In to add comment