我在实现使用模板模板参数的类模板的特化时遇到问题。例如,我想编写一个用于排序的类:
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; ~~~~~~ ^ ~~~~~~~
这是因为它没有找到专业化。
答案 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 );
}