Why does this std :: sort predicate fail if the class is inside main ()?

This is a greatly simplified version that illustrates how class Predicate works outside of < main() , but when the exact code appears as a class InlinePredicate , the compiler cannot match std::sort . The strange thing is that you can pass something as the third argument to std::sort (say, integer 7), and you will only get a compilation error if it does not support operator () , which expects sort . But when I go below pred2 , it does not match at all:

 #include <string> #include <vector> #include <algorithm> using namespace std; class Predicate { public: bool operator () (const pair<string,int>& a, const pair<string,int>& b) { return a.second < b.second; } }; int main() { vector<pair<string, int> > a; Predicate pred; sort(a.begin(), a.end(), pred); class InlinePredicate { public: bool operator () (const pair<string,int>& a, const pair<string,int>& b) { return a.second < b.second; } } pred2; sort(a.begin(), a.end(), pred2); return 0; } 

repro.cc: In the function 'int main ():

repro.cc.30: error: there is no corresponding function to call sorting (__ gnu_cxx :: __ normal_iterator, std :: allocator>, int> *, std :: vector, std :: allocator>, int>, std :: allocator , std :: allocator>, int โ†’ โ†’, __gnu_cxx :: __ normal_iterator, std :: allocator>, int> *, std :: vector, std :: allocator>, int>, std :: allocator, std :: allocator >, int โ†’ โ†’, main () :: InlinePredicate &)

+8
c ++ stl templates
source share
2 answers

In C ++ 03, local classes have no relationship and therefore cannot be used as template arguments (ยง14.3.1 / 2).

In C ++ 0x, this restriction has been removed and your code will compile as is.

+9
source share

In versions C ++ to C ++ 0x, classes declared inside functions cannot be displayed in template parameters. Your call to sort implicitly launches it with a template parameter set to InlinePredicate , which is illegal.

You might want to use either C ++ 0x (with GCC, pass --std=c++0x ; in C ++ 0x this code will work as it is, or you can use anonymous functions) or boost::lambda . With boost::lambda it would look like this:

 using namespace boost::lambda; sort(a.begin(), a.end(), _1 < _2); 
+5
source share

All Articles