实现模板模板参数的部分模板专门化

Implementing partial template specialization of template template parameter

本文关键字:专门化 参数 实现      更新时间:2023-10-16

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

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实现的排序函数。然而,这段代码不起作用。为什么找不到模板专门化?

我得到的错误是:

/应用程序/xcode/内容/开发/工具链/XcodeDefault.xctoolchain/usr/bin/. ./lib/c++/v1/algorithm:3772:40: error: invalid operands到二进制表达式('std::__1::__list_iterator'和'std::__1::__list_iterator')Difference_type __len = __last - __first;~~~~~~ ^ ~~~~~~~

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

为什么要麻烦性状类和部分专门化,而不是简单地重载一个sort函数?俗话说,std::less更多。(Live at Coliru)

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;

为什么不直接使用类型参数呢?:

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