c++ - Template specialization containers -
i open question code sample:
template <template <class, class> class container> class schedule { public: schedule& print( std::ostream& os); private: container<course*, std::allocator<course*> > courses; }; // implement funcion print: template <template <class, class> class container> schedule<container>& schedule<container>::print(std::ostream& os){ std::sort(courses.begin(), courses.end(), sor_con()); std::for_each(courses.begin(), courses.end(), printcontainer(os)); return *this; } template<> schedule<std::list>& schedule<std::list>::print(std::ostream& os){ courses.sort(sort_con()); std::for_each(courses.begin(), courses.end(), printcontainer(os)); return *this; }
the schedule
class contains template classes (std::list / std::vector
) only. because print
function needs use sort, need use 2 different ways implement this: std::sort
std::vector
, sort
function of list container std::list
.
my code works, think created unnecessary code duplication here. there more efficient way solve problem?
you either overload sort
function std::vector
, std::list
respectively:
template<typename t, typename compare> void sort(std::list<t> &list, compare f) { list.sort(f); } template<typename t, typename compare> void sort(std::vector<t> &vector, compare f) { std::sort(vector.begin(), vector.end(), f); }
or use type_traits , tag_dispatching:
#include <iostream> #include <list> #include <vector> #include <algorithm> #include <functional> struct vectorlike_tag { }; struct listlike_tag { }; template <typename c> struct container_traits; template <typename t, typename a> struct container_traits<std::vector<t, a>> { typedef vectorlike_tag category; }; template <typename t, typename a> struct container_traits<std::list<t, a>> { typedef listlike_tag category; }; template <typename container, typename compare> void sort_helper(container& c, compare f, vectorlike_tag) { std::sort(c.begin(), c.end(), f); } template <typename container, typename compare> void sort_helper(container& c, compare f, listlike_tag) { c.sort(f); } template <typename container, typename compare> void sort_container(container &c, compare f) { sort_helper(c, f, typename container_traits<container>::category()); } template<class container> void sort_container(container &c) { sort_helper(c, std::less<typename container::value_type>(), typename container_traits<container>::category()); } int main() { std::vector<int> v{ 4, 3, 7, 8, 9 }; sort_container(v); (auto e : v) std::cout << e << " "; std::cout << std::endl; std::list<int> lst{ 4, 3, 7, 8, 9 }; sort_container(lst, std::greater<int>()); (auto e : lst) std::cout << e << " "; std::cout << std::endl; return 0; }
Comments
Post a Comment