Why "no match for 'operator<'" when I declared it?
<p>It works for the <code>struct xy</code> that I declared. Why doesn't the same pattern work for <code>complex&lt;int&gt;</code>?</p>

<pre><code>#include &lt;complex&gt;
#include &lt;set&gt;
using namespace std;

struct xy {
    int x, y;
};

bool operator&lt; (const xy &amp;a, const xy &amp;b) {
    return a.x &lt; b.x;
}

bool operator&lt; (const complex&lt;int&gt; &amp;a, const complex&lt;int&gt; &amp;b) {
    return a.real() &lt; b.real();
}

int main() {
    xy q;
    set&lt;xy&gt; s;
    s.insert(q);

    complex&lt;int&gt; p;
    set&lt; complex&lt;int&gt; &gt; t;   //If I comment out these two lines,
    t.insert(p);             //it compiles fine.

    return 0;
}
</code></pre>

<p>The error message:</p>

<pre>
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&lt;&gt;::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&lt;&gt; _Rb_tree&lt;&gt;::_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&lt;&gt; _Rb_tree&lt;&gt;::_M_insert_unique(_Arg&&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_set.h:463:29:   required from 'pair&lt;&gt; __cxx1998::set&lt;&gt;::insert(const value_type&)'
c:\m\lib\gcc\mingw32\4.8.1\include\c++\debug\set.h:220:59:   required from 'pair&lt;&gt; __debug::set&lt;&gt;::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: 
<b>error: no match for 'operator&lt;' (operand types are 'const std::complex&lt;int&gt;' and 'const std::complex&lt;int&gt;')
       { return __x &lt; __y; }</b>
</pre>

<p>My best guess is that this has something to do with <code>complex&lt;T&gt;</code> 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?</p>

<p>What I see happening is that the STL at some point tries (roughly speaking) to do <code>a &lt; b</code>, where <code>a</code> and <code>b</code> are <code>complex&lt;int&gt;</code> instances. So it's looking for <code>bool operator&lt; (const complex&lt;int&gt; &amp;a, const complex&lt;int&gt; &amp;b)</code>. Well, there is exactly that declared just above <code>main()</code>. 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.</p>