My system info: Configured with: /home/portage/portage/gcc-3.4.2-r2/work/gcc-3.4.2/configure --enable-version-specific-runtime-libs --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/3.4 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.2/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.2/include/g++-v3 --host=i686-pc-linux-gnu --enable-nls --without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable-shared --with-system-zlib --disable-checking --disable-werror --disable-libunwind-exceptions --with-gnu-ld --enable-threads=posix --disable-multilib --disable-libgcj --enable-languages=c,c++ Thread model: posix gcc version 3.4.2 (Gentoo Linux 3.4.2-r2, ssp-3.4.1-1, pie-8.7.6.5) The following code failes to compile (compiles with "g++ -o blah blah.cpp"): #include <string> #include <set> template<typename T> struct other_sort : public std::binary_function<T, T, bool> { bool operator()(const T &lhs, const T &rhs) const { return lhs < rhs; } }; // Works just fine void f(const std::set<std::string, other_sort<std::string> > &in = std::set<std::string, other_sort<std::string> >()) { } struct test1 { // Parser error void f(const std::set<std::string, other_sort<std::string> > &in = std::set<std::string, other_sort<std::string> >()) const { } // Works just fine. void g(const std::set<std::string, other_sort<std::string> > &in) const { } }; struct test2 { typedef other_sort<std::string> sort_td; // Parser error void f(const std::set<std::string, sort_td> &in = std::set<std::string, sort_td>()) const { } // Works just fine. void g(const std::set<std::string, sort_td> &in) const { } }; struct test3 { typedef std::set<std::string, other_sort<std::string> > set_td; // Works just fine. void f(const set_td &in = set_td()) const { } // Works just fine. void g(const set_td &in) const { } }; int main() { test1 x; x.f(); test2 y; y.f(); test3 z; z.f(); return 0; } With the following errors: blah.cpp:20: error: expected `,' or `...' before '>' token blah.cpp:20: error: missing `>' to terminate the template argument list blah.cpp:20: error: template argument 1 is invalid blah.cpp:20: error: template argument 2 is invalid blah.cpp:20: error: template argument 3 is invalid blah.cpp:36: error: expected `,' or `...' before '>' token blah.cpp:36: error: missing `>' to terminate the template argument list blah.cpp:36: error: template argument 1 is invalid blah.cpp:36: error: template argument 2 is invalid blah.cpp:36: error: template argument 3 is invalid blah.cpp: In function `int main()': blah.cpp:64: error: no matching function for call to `test1::f()' blah.cpp:21: note: candidates are: void test1::f(const std::set<std::string, other_sort<std::string>, std::allocator<std::string> >&, other_sort<std::string>) const blah.cpp:66: error: no matching function for call to `test2::f()' blah.cpp:37: note: candidates are: void test2::f(const std::set<std::string, other_sort<std::string>, std::allocator<std::string> >&, other_sort<std::string>) const I can post the assembly code if you REALLY want, however I've tried this with gcc 3.3.4 and gcc 3.4.2, and all the code above is using all the standard STL that comes with those distributions, without modification. As you can see from the above comments, if I typedef the set, it works fine.
The standard is not clear what should happen here, some places suggest it should be rejected. Anyways this is a dup of bug 57 (I think the oldest c++ bug which is still open). *** This bug has been marked as a duplicate of 57 ***