【问题标题】:sort container of pointers c++ and compare type对指针c ++的容器进行排序并比较类型
【发布时间】:2014-07-05 04:00:01
【问题描述】:

我需要排序容器。 但我从模板中获取容器的类型.. 因为这个我需要使用std::sort 代表std::vectorname.sort 代表std::list。 因此我需要检查容器的类型以便选择要做什么。

我尝试做:

class sor {
public:
    sor(){}
    bool operator( )(Course* l, Course* r) {
        return l->getNumber() < r->getNumber();
    }
};



if (typeid(courses) == std::list){
    //do something...
}
else{
   //do...
} 

我该怎么做? 谢谢

【问题讨论】:

    标签: c++ sorting containers


    【解决方案1】:

    std::sort 算法在某种程度上是独立于容器的(它需要迭代器来满足 ValueSwappableRandomAccessIterator 的要求),因此您可以像这样使用它:

    std::sort(container.begin(), container.end(), sor());
    

    不幸的是,std::list 不满足 RandomAccessIterator


    如果您有一个接受任何容器类型的模板函数,您可以为其提供特化。或者,使用type traits,您可以提供更通用的模板“重载”:

    template<class... Args, template<class...> class Container>
    void sort(Container<Args...>&) { ... }
    
    template<class... Args>
    void sort(std::list<Args...>&) { ... }
    

    Live demo

    【讨论】:

    • 那么我该如何比较这些类型呢?
    • @user3630497,为什么需要比较类型?还有,模板函数在哪里?
    • 我需要比较类型,因为我想将 std::sort 用于 std::vector。并为 std::list 使用某种列表
    • 我无法在 tham 之间进行比较?
    • std::list::sort 具有通常的 O(NlogN) 复杂性。据我所知,它没有(大量)额外的内存使用。所以我不确定你的评论是关于什么的。
    【解决方案2】:

    你可以重载你自己的排序函数

    template<typename T, typename Compare>
    void sort(std::list<T>& list, Compare compare)
    {
        list.sort(compare);
    }
    
    template<typename T, typename Compare>
    void sort(std::vector<T>& vector, Compare compare)
    {
        std::sort(vector.begin(),vector.end(),compare);
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用type traitstag 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;
      }
      

      输出:

      3 4 7 8 9

      9 8 7 4 3

      【讨论】:

        猜你喜欢
        • 2014-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-15
        • 1970-01-01
        • 2016-11-29
        相关资源
        最近更新 更多