there is the following piece of C++ code ------------------------------------------------------------ #include <iostream> const int Dim = 3; typedef double Point[Dim]; #ifdef __FOO1__ template< class T > int foo( T &v ) { return 0; } #endif #ifdef __FOO2__ int foo( Point &v ) { return 0; } #endif #ifdef __OP1__ template< class T > bool operator<( T &v1, T &v2 ) { return false; } #endif #ifdef __OP2__ bool operator<( Point &v1, Point &v2 ) { return false; } #endif int main() { Point p; std::cout << foo(p) << std::endl; std::cout << (p < p) << std::endl; return 0; } ------------------------------------------------------------ g++ from kubuntu 6.10 with user:~$ g++ -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release x86_64-linux-gnu Thread model: posix gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5) produces the following user:~$ g++ test.cxx -D __FOO1__ -D __OP1__ user:~$ g++ test.cxx -D __FOO1__ -D __OP2__ test.cxx:22: error: ‘bool operator<(double (&)[3], double (&)[3])’ must have an argument of class or enumerated type user:~$ g++ test.cxx -D __FOO2__ -D __OP1__ user:~$ g++ test.cxx -D __FOO2__ -D __OP2__ test.cxx:22: error: ‘bool operator<(double (&)[3], double (&)[3])’ must have an argument of class or enumerated type So my question is, why the operator in __OP2__ is treated differently as the function in __FOO2__ ?