daily pastebin goal
61%
SHARE
TWEET

Untitled

a guest Nov 18th, 2017 44 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
Top