模板专业化容器

时间:2014-05-17 19:21:18

标签: c++ templates containers specialization duplication

我将使用代码示例打开问题:

 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;
     }

Schedule类仅包含模板类(std::list / std::vector)。由于print函数需要使用sort,我需要使用两种不同的方法来实现这一点:std::sort来自std::vectorsort函数的列表容器{{1} }。

我的代码有效,但我认为我在这里创建了不必要的代码重复。有没有更有效的方法来解决这个问题?

1 个答案:

答案 0 :(得分:2)

你可以分别为sortstd::vector重载std::list函数:

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);
}

或使用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);
  for (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>());
  for (auto e : lst) std::cout << e << " ";
  std::cout << std::endl;
  return 0;
}