The specialization of nested template class is not found if the outer class is also a template class.
We need a full testcase, can you provide one?
Created attachment 5153 [details] Shows output with/without templatized outer class The output below the line: run output for DEFS= should be what occurs below the line: run output for DEFS=-DTEMPL_PCHILDREN
Subject: Re: templatizing outer class hides specialization of inner template class On 11/17/2003 12:36 PM, pinskia at gcc dot gnu dot org wrote: >------- Additional Comments From pinskia at gcc dot gnu dot org 2003-11-17 18:36 ------- >We need a full testcase, can you provide one? > > > Just did. Didn't include the .ii because it was too large.
You boost guys really have ways to write totally incomprehensible testcases... Anyway, the claim is justified, I guess. In essence, this boils down to ------------------ #include <iostream> template <typename> struct S { template <typename> struct Type {}; }; template <typename> struct X { template <typename> struct Local; }; template <typename U> template <typename> struct X<U>::Local { static void id() { std::cout << "primary\n" ;} }; template <typename U> template <typename T> struct X<U>::Local<typename S<U>::template Type<T> > { static void id() { std::cout << "specialized\n" ;} }; int main() { X<int>::Local<S<int>::Type<int> >::id(); } ------------------------------- For this, we get g/x> /home/bangerth/bin/gcc-3.3.2/bin/c++ x.cc ; ./a.out primary The same holds for every other gcc version that doesn't ICE outright. On the other hand, icc for example prints "specialized". I guess it's wrong that we don't match the partial specialization of X::Local. W.
Just as a random factoid, the Compaq compiler thinks: cxx: Error: test.cc, line 20: a partial specialization of a member class template must be declared in the class of which it is a member struct X<U>::Local<typename S<U>::template Type<T> > { -------------^ cxx: Info: 1 error detected in the compilation of "test.cc". I don't have enough C++-fu to know whether it is right.
Subject: Re: templatizing outer class hides specialization of inner template class On 11/17/2003 04:05 PM, falk at debian dot org wrote: >------- Additional Comments From falk at debian dot org 2003-11-17 22:05 ------- >Just as a random factoid, the Compaq compiler thinks: > >cxx: Error: test.cc, line 20: a partial specialization of a member class > template must be declared in the class of which it is a member >struct X<U>::Local<typename S<U>::template Type<T> > { >-------------^ >cxx: Info: 1 error detected in the compilation of "test.cc". > >I don't have enough C++-fu to know whether it is right > > I think Compaq is right :( See http://www.comeaucomputing.com/iso/cwg_defects.html#44
Created attachment 5158 [details] simplified code with specialization declared withing outer class The .gz file contains makefile, run output, and simplified code which more closely resembles requirements of section 14.7.3 of standard and section 14.5.4. The item 6 in section 14.5.4 seems pretty close to what I've got; hence, I believe it's a bug.
Created attachment 5250 [details] comparison with como compiler The attachment, cycle_mgr_curry_visitor_special.como-gxx.tar.gz, contains another example of this bug. the difference is that 2 template parameters are needed to reveal the problem. With only 1, e.g. with template-id cycle_mgr<curry_visitor_referent<Visitor>::template owner<Referent> >, the como compiler won't choose the right int cycle_mgr<...>::rc. OTOH, with the 2nd template paramenter, como, as demonstrated in the .out file in the tar.gz attachement, does select the rc which returns 0.
(In reply to comment #6) > Subject: Re: templatizing outer class hides specialization > of inner template class > > On 11/17/2003 04:05 PM, falk at debian dot org wrote: > > >------- Additional Comments From falk at debian dot org 2003-11-17 22:05 ------- [snip] > I think Compaq is right :( See > http://www.comeaucomputing.com/iso/cwg_defects.html#44 > Closer reading of the defect report changed my mind. In particular, the line: Proposed resolution (04/01): In-class specializations of member templates are not allowed. Hence, Compaq must be wrong, unless there are different rules for partial specializations. Will have to check on that. Furthermore, the examples in paragraph 17 of 14.7.3 show examples of out-of-class specializations.
(In reply to comment #9) > (In reply to comment #6) [snip] > Hence, Compaq must be wrong, unless there are different rules for partial > specializations. Will have to check on that. The exmample code in paragraph 6 of section 14.5.4 supports the above conclusion, i.e. Compaq is wrong about partial specialization of member class template having to be declared in the class of which it is a member.
Created attachment 5318 [details] More variations in template args and resuting output and como compare This contains more variations in template arg types and corresponding output and comparison with como.
Created attachment 5817 [details] Workaround to move T's in nondeduced to deduced contexts The standard, at 14.8.2.4p4, indicates T and T2 in A<T>::B<T2> are in nondeduced context and don't participate in template argument deduction. This code shows a way to force participation.
John Spicer at Edg convinced me it wasn't a bug by citing the standard 14.8.2.4p4. Bug maybe should be changed to resolved or not valid.
Created attachment 5821 [details] correction by substituting value of Outer template arg in nondeduced specialization This is just a slight correction to make the nondeduced as close as possible to deduced specialization.
Created attachment 5860 [details] revised test case passing for intel, failing for g++20040225 This zip contains code and output for g++ downloaded from: http://www.binarycode.org/gcc/snapshots/3.4-20040225/gcc-g++-3.4-20040225.tar.bz2 It also contains output for this g++ and intel8.0. The two ouputs differ; however, I believe intel's is correct, especially since John Spicer at edg has run a new version on the code and it gets same output as my intel8.0. There's been discussion on this topic on comp.lang.c++.moderated as shown here: http://groups.google.com/groups?q=nondeduced+group:comp.lang.c%2B%2B.moderated&hl=en&lr=&ie=UTF-8&group=comp.lang.c%2B%2B.moderated&selm=10422s0n4gtdaac%40corp.supernews.com&rnum=1
The latest attachment, nested_deduction.zip, compares intel and g++ output, which differ. I believe intel's is right; hence, there's still a bug in g++. The g++ dated 20040225 was used in the test shown in attachment.
Although last test was on 3.4, the same error occurs in 3.3. I've just entered the same bug, #14447, for gcc-3.4.
*** Bug 14447 has been marked as a duplicate of this bug. ***
I should note that the last attached testcase ICE on the compiler, I filed PR 15818 for that ICE.
Will investigate.
The testcase nested_deduction.cpp works now. However the code in comment #4 still doesn't work due to a flaw in template argument deduction. We are deducing 'U' and 'T' together at the same time in template <typename U> template <typename T> struct X<U>::Local<typename S<U>::template Type<T> > rather than first substituting 'U' with 'int' and then deducing 'T'.
Still present on mainline...
See also PR 4882. W.
Work postponed to GCC 4.1. This bug is tricky to fix.
Won't work on it for a long while.
There is actually two different bugs here. The original bug is a (rather convoluted) duplicate of 4882. It still remains unresolved as of gcc-4.1. The nested_deduction.zip source, which was submitted much later, demonstrated a different problems. Nested templates didn't match on template template specializations. A vastly simplified (over the nested_deductions code) example is: template<typename> struct A { template<typename> struct B { }; }; template<typename> struct C { }; template<template<typename> class c,typename t> struct C<c<t> > { typedef int type; }; int main(void) { C<A<void> >::type val0 = 0; C<A<void>::B<void> >::type val1 = 0; // Dies here return val0+val1; } With earlier versions of gcc, this would give the error Simplified.cpp:17: error: `type' is not a member of type `C<A<void>::B<void> >', with gcc 4.1 it now compiles fine. I appear, however, to not have the power to change the status of this report, so someone else will have to.
It seems to me that lately everything is fine.