------- Comment #2 from dodji at gcc dot gnu dot org 2009-10-23 10:58 ------- I am not sure the example is invalid.
The Dummy()(Gen()) call expression obviously selects the operator "template <typename F> typename F::template Sig<>::ResultType operator()(F const& f) const" in Dummy. I believe the critical question is the following: In: ~=~ template <typename R> struct CFunType { template <class Dummy1=Void, class Dummy2=Void> struct Sig: public FunType<WrongNumberOfSigArgs> { };//#1 template <class Dummy> struct Sig<Void,Dummy> : public FunType<R> { };//#2 }; ~=~ Which Sig template is instantiated by "typename F::template Sig<>" ? Is it //#1 or //#2 ? I think Sig<> matches the template #1 (as in Sig<void,void>) which is the primary template. But then, the best specialization of #1 is selected by the compiler. The arguments of that specialization are deduced from the arguments of the primary template. The <void,void> argument list used to match the primary template #1 is compatible with the parameters of the specialization #2. So in the end it's #2 that is going to be instantiated. The relevant parts of the C++ spec are, I believe, the following: [temp.class.spec] 7. "Partial specialization declarations themselves are not found by name lookup. Rather, when the primary template name is used, any previously-declared partial specializations of the primary template are also considered." [temp.class.spec.match] 1. "When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations. This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations." That being said, the crash seems to happens later during the mangling of the operator "template <typename F> typename F::template Sig<>::ResultType operator()(F const& f) const", precisely on the Sig<> template-id because the mangling code doesn't expect the template argument list to be empty. -- dodji at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- AssignedTo|unassigned at gcc dot gnu |dodji at gcc dot gnu dot org |dot org | Status|NEW |ASSIGNED Last reconfirmed|2009-08-25 14:16:58 |2009-10-23 10:58:13 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40808