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

时间:2014-07-02 12:12:16

标签: c++ templates c++11 template-specialization template-templates

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

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

我使用list的特化,因为我想调用std :: list实现的sort函数。但是,这段代码不起作用。为什么没有找到模板专业化?

我得到的错误是:

  

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin /../ lib / c ++ / v1 / algorithm:3772:40:错误:操作数无效         到二进制表达式('std :: __ 1 :: __ list_iterator'和'std :: __ 1 :: __ list_iterator')           difference_type __len = __last - __first;                                   ~~~~~~ ^ ~~~~~~~

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

2 个答案:

答案 0 :(得分:3)

为什么要干扰traits类和部分特化而不是简单地重载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;

答案 1 :(得分: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 );
}