It works for the struct xy that I declared. Why doesn't the same pattern work for complex<int>?
#include <complex>
#include <set>
using namespace std;
struct xy {
    int x, y;
};
bool operator< (const xy &a, const xy &b) {
    return a.x < b.x;
}
bool operator< (const complex<int> &a, const complex<int> &b) {
    return a.real() < b.real();
}
int main() {
    xy q;
    set<xy> s;
    s.insert(q);
    complex<int> p;
    set< complex<int> > t;   //If I comment out these two lines,
    t.insert(p);             //it compiles fine.
    return 0;
}
The error message:
In file included from c:\m\lib\gcc\mingw32\4.8.1\include\c++\string:48:0,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\locale_classes.h:40,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\ios_base.h:41,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\ios:42,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\istream:38,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\sstream:38,
                 from c:\m\lib\gcc\mingw32\4.8.1\include\c++\complex:45,
                 from test.cpp:1:
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_function.h: In instantiation of 'bool less<>::operator()(const _Tp&, const _Tp&) const':
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_tree.h:1321:11:   required from 'pair<> _Rb_tree<>::_M_get_insert_unique_pos(const key_type&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_tree.h:1374:47:   required from 'pair<> _Rb_tree<>::_M_insert_unique(_Arg&&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_set.h:463:29:   required from 'pair<> __cxx1998::set<>::insert(const value_type&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\debug\set.h:220:59:   required from 'pair<> __debug::set<>::insert(const value_type&)'
test.cpp:28:19:   required from here
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_function.h:235:20: 
error: no match for 'operator<' (operand types are 'const std::complex<int>' and 'const std::complex<int>')
       { return __x < __y; }
My best guess is that this has something to do with complex<T> being a class, not a struct. By I can't see the logic of why that should make a difference. Or is it some template horribleness?
What I see happening is that the STL at some point tries (roughly speaking) to do a < b, where a and b are complex<int> instances. So it's looking for bool operator< (const complex<int> &a, const complex<int> &b). Well, there is exactly that declared just above main(). Why is it being unreasonable? I thought maybe it didn't like them being references. But removing the ampersands made no difference to its complaint.
 
     
     
    