This is a much simplified repro which illustrates how class Predicate
delcared outside main()
works but when the exact code appears inline as class InlinePredicate
the compiler can't match std::sort
. The strange thing is that you can pass anything as the third argument to std::sort
(say, integer 7) and you'll just get a compile error when it does not support the operator ()
that sort
expects. But when I pass pred2
below it doesn't 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 function ‘int main()’:
repro.cc:30: error: no matching function for call to ‘sort(__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&)’
In C++03, local classes have no linkage and consequently cannot be used as template arguments (§14.3.1/2).
In C++0x, this limitation has been removed and your code would compile as-is.
In versions of C++ prior to C++0x, classes declared inside functions cannot appear in template parameters. Your invocation of sort
implicitly instantiates it with a template parameter set to InlinePredicate
, which is illegal.
You may want to consider using either C++0x (with GCC, pass --std=c++0x
; in C++0x this code will work as-is, or you can use anonymous functions instead), or boost::lambda
. With boost::lambda
, it would look like this:
using namespace boost::lambda;
sort(a.begin(), a.end(), _1 < _2);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With