Recursive generic function used as a predicate, compilation failure

I am writing a function to compare the contents of two lists. The order of the elements doesn't matter, so I sort them before comparing. Lists can have the usual types list<int> , as well as list lists list<list<int> > .

Here is a complete stripped-down example:

 #include <list> template <typename T> bool lessThanInAnyOrder(T lhs, T rhs) { return lhs < rhs; } template <typename T> bool lessThanInAnyOrder(std::list<T> lhs, std::list<T> rhs) { lhs.sort(lessThanInAnyOrder<T>); rhs.sort(lessThanInAnyOrder<T>); //Do comparisons here, but for now just: return false; } int main() { std::list<int> list1; std::list<int> list2; lessThanInAnyOrder(list1, list2); } 

This compiles in GCC 4.3.3, but in Visual Studio 2008 it gives the following compilation error when I call lhs.sort() :

 error C2660: 'std::list<_Ty>::sort' : function does not take 1 arguments 

Any suggestions?

+4
source share
4 answers

Wrap the function in std::ptr_fun with explicit type arguments:

 lhs.sort(std::ptr_fun<T, T>(lessThanInAnyOrder<T>)); 
+2
source

A compilation error because the compiler cannot select the overloaded lessThanInAnyOrder function to go to the :: sort list. You must specify it explicitly, as here .

 template <typename T> bool lessThanInAnyOrder(std::list<T> lhs, std::list<T> rhs) { bool (*comparer)(T, T) = &lessThanInAnyOrder<T>; lhs.sort(comparer); rhs.sort(comparer); //Do comparisons here, but for now just: return false; } 
+3
source

At first . I suggest that if you want to compare collections regardless of their ordering, you can search for std::set with set_difference , set_intersection , set_union and set_symmetric_difference

To your question

You are trying to implement sort-by-policy; if you canโ€™t just specialize std::less<> (which exists for this specific purpose), you can knock down the user policy yourself: ( code that runs on code code. Org )

 #include <list> #include <vector> #include <iostream> #include <iterator> #include <algorithm> namespace applogic { template <typename T> struct sort_policy { typedef std::less<T> predicate_t; }; template <> struct sort_policy<std::string> { struct _Cmp { bool operator()(const std::string& a, const std::string& b) { return a.length()>b.length(); } }; typedef _Cmp predicate_t; }; template <typename C> void sort(C& cont) { typedef typename sort_policy<typename C::value_type>::predicate_t P; std::sort(cont.begin(), cont.end(), P()); } template <typename T> void sort(std::list<T>& cont) { typedef typename sort_policy<T>::predicate_t P; cont.sort(P()); } } template <class C> static void dump(const C& cont, const std::string& msg="") { std::cout << msg; std::copy(cont.begin(), cont.end(), std::ostream_iterator<typename C::value_type>(std::cout, ", ")); std::cout << std::endl; } int main() { using applogic::sort; std::vector<int> ints; ints.push_back(13); ints.push_back(-3); ints.push_back(7); dump(ints, "before: "); sort(ints); dump(ints, "after: "); std::list<std::string> strings; strings.push_back("very very long"); strings.push_back("tiny"); strings.push_back("medium size"); dump(strings, "before: "); sort(strings); dump(strings, "after: "); return 0; } 
+3
source

My guess is, for type int you can simply write like this:

 lhs.sort(); rhs.sort(); 

Demo version

0
source

All Articles