The fact that std::pair has operator>= defined in namespace std "hides" oprator>= defined in namespace std::rel_ops, for all classes. operator>= for pairs is defined in <bits/stl_pair.h>, and it is in namespace std; This only happens when " >= " is used from std, as in the case of "greater_equal". I use >= as an example, the same happens for (<=, >, .....) I've tested this behavior with gcc 4.4.0 (on Fedora 11), gcc 4.3.X and 3.4.X from cygwin. This small c++ program fails with (compiled as g++ -c foo.cpp) (If I add -Wall, it reports about ok and bad not being used). In file included from /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/functional:51, from foo.cpp:3: /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_function.h: In member function ‘bool std::greater_equal<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = A]’: foo.cpp:20: instantiated from here /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_function.h:239: error: no match for ‘operator>=’ in ‘__x >= __y’ #include <utility> #include <functional> using namespace std; using namespace std::rel_ops; struct A { bool operator<(const A &) const; }; void foo1() { bool ok = A() >= A(); // just to check rel_ops is actually included } void foo2() { greater_equal<A> ge; bool bad = ge(A(), A()); } The only way to make it compile so far is to add namespace std { namespace rel_ops { } using namespace rel_ops; } so that rel_ops::operator>= is found by "greater_equal". If I only add using namespace std::rel_ops; in my C++ source code, it is not enough, since (I think) gcc chooses (while parsing greater_equal) the operator>= defined in std (the only one available at that time), and when an other one is added later (from rel_ops) it is too late. Alternatively, if I move operator>= for pair into std::rel_ops everything works. I am not sure where is the root of the problem, but my thoughts are 1) why do we need an operator >= for pair? is it not enough the one for all <T>? 2) why is operator>= for pair in std and not in std::rel_ops? 3) is gcc correct in ignoring operator>= from rel_ops?
Created attachment 18227 [details] Preprocessed file to reproduce the error. Filed obtained with g++ -E foo.cpp -o foo.i to reproduce the issue.
using namespace std; using namespace std::rel_ops; is the problem. You are changing name-lookup results. With arbitrary using directives you can get to arbitrary name-lookup results.
I have removed one of the "using" and still get the same problem: #include <utility> #include <functional> using namespace std::rel_ops; struct A { bool operator<(const A &) const; }; void foo1() { bool ok = A() >= A(); // just to check rel_ops is actually included } void foo2() { std::greater_equal<A> ge; bool bad = ge(A(), A()); } An alternative way is to replace the "using namespace std::rel_ops;" with using std::rel_ops::operator>=; but this means I have to repeat it for every operator I need. Is there an other way to make all operators defined in rel_ops available?
Use it in struct A: struct A { using std::rel_ops; bool operator<(const A &) const; }; ADL (also known as Koenig lookup) will then find it for arguments of type A. it's really not a good idea to globally import pieces of the standard namespace (using std; is an execption because it's just used so widely).
Thanks for your detailed answer.
In general, I recommend being wary of anything having to do with rel_ops: most of the authors of the original C++03 standard have today a very low opinion of it, essentially consider it irreparably broken.