-2

我在实现使用模板模板参数的类模板的专业化时遇到问题。例如,我想写一个用于排序的类:

template <template <typename, typename...> class container_type> struct SortTraits {

  template <class comparator_type>
  static void sort(container_type<size_t> &front, comparator_type comp) {
    std::sort(front.begin(), front.end(), comp);
  }
};


template <> struct SortTraits<std::list> {

  template <class T, class comparator_type>
  static void sort(std::list<T> &front, comparator_type comp) {
    front.sort(comp);
  }
};

然后我会这样称呼它:

struct MyFunctor {
  bool operator()( const size_t& a, const size_t& b ) const {
    return a>b;
  }
};

//! Alias template used for the type of container used to store a front
template <class T> using container_template = std::list<T>;

int main(int argc, char *argv[]) {

  //! Concrete type for a front
  typedef container_template<size_t> front_type;


  front_type myContainer = {3,5,2,6,3,6,7};

  MyFunctor mySortFunctor;

  SortTraits<container_template>::sort(myContainer, mySortFunctor);

  for (auto it = myContainer.begin(); it != myContainer.end(); ++it)
    cout<<" "<<*it;
  cout<<endl;
  exit(0);
}

我使用列表的特化,因为我想调用 std::list 实现的排序函数。但是,此代码不起作用。为什么找不到模板专业化?

我得到的错误是:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:3772:40:错误:二进制表达式的操作数无效('std::__1: :__list_iterator' 和 'std::__1::__list_iterator') 区别类型 __len = __last - __first; ~~~~~~ ^ ~~~~~~~

这是因为它没有找到专业化。

4

2 回答 2

3

为什么要为特质类和偏特化而不是简单地重载一个sort函数而烦恼呢?俗话说,std::less事半功倍。(住在科利鲁

template <typename Container>
using less = std::less<
  typename std::decay<
    decltype(*std::declval<Container&>().begin())
  >::type
>;

template<typename Container, typename Compare = less<Container>>
inline void sort(Container& container, Compare&& comp = {}) {
    using std::begin;
    using std::end;
    std::sort(begin(container), end(container), std::forward<Compare>(comp));
}

template<typename... T, typename Compare = less<std::list<T...>>>
inline void sort(std::list<T...>& list, Compare&& comp = {}) {
    list.sort(std::forward<Compare>(comp));
}

就此而言,如果成员存在时sort首选成员的通用函数sort将完全省去编写重载的麻烦(Live at Coliru):

namespace detail {
using std::begin;
using std::end;

template<typename Container, typename Compare>
inline void sort_(Container& container, Compare&& comp, ...) {
    std::sort(begin(container), end(container), std::forward<Compare>(comp));
}

template<typename Container, typename Compare>
inline auto sort_(Container& container, Compare&& comp, int) ->
  decltype(container.sort(std::forward<Compare>(comp))) {
    return container.sort(std::forward<Compare>(comp));
}

template<typename Container, typename Compare = std::less<
  typename std::decay<
    decltype(*begin(std::declval<Container&>()))
  >::type
>>
inline void sort(Container& container, Compare&& comp = {}) {
    sort_(container, std::forward<Compare>(comp), 0);
}
} // namespace detail
using detail::sort;
于 2014-07-02T14:20:30.807 回答
0

为什么不只使用类型参数?:

template<typename CONTAINER>
struct SortTraits
{
    template<typename COMPARATOR>
    static void sort( CONTAINER&  container , COMPARATOR comparator = std::less<> )
    {
        std::sort( std::begin( container ) , std::end( container ) , comparator );
    }
};

template<typename T>
struct SortTraits<std::list<T>>
{
    template<typename COMPARATOR>
    static void sort( std::list<T>&  list , COMPARATOR comparator )
    {
        list.sort( comparator );
    }
};

namespace utils
{
    template<typename CONTAINER , typename COMPARATOR>
    void sort( CONTAINER& container , COMPARATOR comparator )
    {
        SortTraits<CONTAINER>::sort( container , comparator );
    }
}

int main()
{
    std::array<int,4> arr = { 1 , 2 , 3 , 4 };
    std::list<int> list = { 1 , 2 , 3 , 4 };
    std::vector<int> vec = { 1 , 2 , 3 , 4 };

    utils::sort( arr );
    utils::sort( list );
    utils::sort( vec );
}
于 2014-07-02T12:25:53.180 回答