Saturday, October 29, 2016

using iterator_trait to get iterator type to *value and iterator category template specialization to get iter type


tag dispatching--template specialization can be based on the tag

So Dispatch() can pass in typename iterator_traits<T>::iterator_category() to find matching specialization
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <list>
#include <iterator>
#include <forward_list>

using namespace std;

template<typename InputIter, typename Func>
void adjacent_pair2(InputIter first, InputIter last, Func func)
{
 if (first != last)
 {
  typename std::iterator_traits<InputIter>::value_type trailer = *first;
  //auto trailer = *first;  // C++ 11,14 cannot tell type
  ++first;
  for (; first != last; ++first)
  {
   func(trailer, *first);
   trailer = *first;
  }
 }
};

template<class C>
void print_iter_category(C c, std::random_access_iterator_tag)
{
 cout << "from random iter tag specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::bidirectional_iterator_tag)
{
 cout << "from bi-direct iter tag specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::input_iterator_tag)
{
 cout << "from input iter specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::output_iterator_tag)
{
 cout << "from output iter specialization" << endl;
}

template<class C>
void print_iter_category(C c, std::forward_iterator_tag)
{
 cout << "from fwd iter specialization" << endl;
}

template<typename T>
void Show(T t)
{
 print_iter_category(t, typename iterator_traits<T>::iterator_category());
 print_iter_category(t, iterator_traits<T>::iterator_category());;
}


int main()
{
 vector<int> v = { 2,16,36,109,8,999,90,5 };

 func_cout a_func;
 adjacent_pair2<vector<int>::iterator, func_cout>(v.begin(), v.end(),a_func);

 list<int> l;
 Dispatch(l.end());  /bi-dir

 Dispatch(v.begin()); // vector is random iter

 istream_iterator<int> isIter;
 Dispatch(isIter);
 
 ostream_iterator<int> osIter(cout);
 Dispatch(osIter);

 forward_list<int> fl;
 Dispatch(fl.begin());   //fwd

 std::string s;
 getline(cin, s);
    return 0;
}



No comments:

Post a Comment