Bug 13088 - templatizing outer class hides specialization of inner template class
Summary: templatizing outer class hides specialization of inner template class
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
: 14447 (view as bug list)
Depends on: 15818
Blocks:
  Show dependency treegraph
 
Reported: 2003-11-17 18:26 UTC by Larry Evans
Modified: 2013-06-07 11:25 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.8.0, 4.9.0
Known to fail:
Last reconfirmed: 2006-01-20 00:56:39


Attachments
Shows output with/without templatized outer class (2.81 KB, text/plain)
2003-11-17 18:42 UTC, Larry Evans
Details
simplified code with specialization declared withing outer class (2.88 KB, application/gzip)
2003-11-18 04:03 UTC, Larry Evans
Details
comparison with como compiler (2.35 KB, application/gzip)
2003-12-01 14:24 UTC, Larry Evans
Details
More variations in template args and resuting output and como compare (2.52 KB, application/gzip)
2003-12-12 04:23 UTC, Larry Evans
Details
Workaround to move T's in nondeduced to deduced contexts (530 bytes, text/plain)
2004-02-28 21:25 UTC, Larry Evans
Details
correction by substituting value of Outer template arg in nondeduced specialization (517 bytes, text/plain)
2004-02-29 18:39 UTC, Larry Evans
Details
revised test case passing for intel, failing for g++20040225 (1.42 KB, text/plain)
2004-03-04 17:32 UTC, Larry Evans
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Larry Evans 2003-11-17 18:26:54 UTC
The specialization of nested template class is not found if
the outer class is also a template class.
Comment 1 Andrew Pinski 2003-11-17 18:36:46 UTC
We need a full testcase, can you provide one?
Comment 2 Larry Evans 2003-11-17 18:42:33 UTC
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
Comment 3 Larry Evans 2003-11-17 18:44:28 UTC
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.


Comment 4 Wolfgang Bangerth 2003-11-17 22:00:44 UTC
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.
Comment 5 Falk Hueffner 2003-11-17 22:05:09 UTC
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.
Comment 6 Larry Evans 2003-11-18 00:28:07 UTC
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


Comment 7 Larry Evans 2003-11-18 04:03:16 UTC
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.
Comment 8 Larry Evans 2003-12-01 14:24:31 UTC
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.
Comment 9 Larry Evans 2003-12-03 15:10:12 UTC
(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.
Comment 10 Larry Evans 2003-12-03 16:25:42 UTC
(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.
Comment 11 Larry Evans 2003-12-12 04:23:52 UTC
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.
Comment 12 Larry Evans 2004-02-28 21:25:56 UTC
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.
Comment 13 Larry Evans 2004-02-28 21:29:24 UTC
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.


Comment 14 Larry Evans 2004-02-29 18:39:22 UTC
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.
Comment 15 Larry Evans 2004-03-04 17:32:39 UTC
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
Comment 16 Larry Evans 2004-03-04 17:34:59 UTC
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.
Comment 17 Larry Evans 2004-03-05 14:38:48 UTC
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.
Comment 18 Giovanni Bajo 2004-03-05 14:42:37 UTC
*** Bug 14447 has been marked as a duplicate of this bug. ***
Comment 19 Andrew Pinski 2004-06-04 05:24:57 UTC
I should note that the last attached testcase ICE on the compiler, I filed PR 15818 for that ICE.
Comment 20 Kriang Lerdsuwanakij 2004-07-19 16:11:02 UTC
Will investigate.
Comment 21 Kriang Lerdsuwanakij 2004-07-19 16:29:26 UTC
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'.
Comment 22 Wolfgang Bangerth 2004-08-16 18:52:15 UTC
Still present on mainline... 
Comment 23 Wolfgang Bangerth 2004-10-15 14:55:43 UTC
See also PR 4882. 
W. 
Comment 24 Kriang Lerdsuwanakij 2004-11-28 10:47:01 UTC
Work postponed to GCC 4.1.  This bug is tricky to fix.
Comment 25 Kriang Lerdsuwanakij 2005-10-22 13:57:00 UTC
Won't work on it for a long while.
Comment 26 Tyson Whitehead 2007-02-16 15:04:22 UTC
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.
Comment 27 Paolo Carlini 2013-06-07 11:25:13 UTC
It seems to me that lately everything is fine.