This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c++/10394: type inference gets confused during template instantiation
- From: colby at alum dot mit dot edu
- To: gcc-gnats at gcc dot gnu dot org
- Date: 13 Apr 2003 21:34:34 -0000
- Subject: c++/10394: type inference gets confused during template instantiation
- Reply-to: colby at alum dot mit dot edu
>Number: 10394
>Category: c++
>Synopsis: type inference gets confused during template instantiation
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: rejects-legal
>Submitter-Id: net
>Arrival-Date: Sun Apr 13 21:36:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Christopher Colby
>Release: 3.2.2
>Organization:
>Environment:
Windows XP
>Description:
Enclosed is a small test program with class A templated by <class T> and class C templated by <class V>. C expects V to define a type V::X and instantiates A with that type. In C's constructor, there are two occurrences of A<typename V::X>. The first occurrence correctly instantiates A with V::X, but the second occurrence erroneously instantiates A with V, thus causing the compiler to reject the program.
Tweaking the enclosed demonstration program in almost any way makes this error disappear. For instance, line #1 compiles, but line #2 generates the type error:
#1 C<E> c(A<int>());
#2 A<int> a; C<E> c(a);
Also, removing the unused template argument from A's templated subclass B also eliminates the type error.
>How-To-Repeat:
Read the comments in main() before compiling the program.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="test.cpp"
Content-Disposition: inline; filename="test.cpp"
template <class T> class A {
public:
template <class U> class B {};
void f(B<int>) {}
};
template <class V> class C {
public:
C(A<typename V::X> a) { a.f(A<typename V::X>::B<int>()); }
};
template <class V> class D {
public:
D(A<typename V::X>* a) { a->f(A<typename V::X>::B<int>()); }
};
class E {
public:
typedef int X;
};
int main() {
A<int> a;
// When you uncomment one of the following four lines...
// C<E> c(A<int>()); // okay; see [1] below.
// C<E> c(a); // compile error; see [2] below.
// D<E> d(new A<int>()); // compile error; see [3] below.
// D<E> d(&a); // compile error; see [4] below.
}
/*
c:\cygwin\home\Christopher Colby\df>g++ -v
g++ -v
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.2.2/specs
Configured with: ../src/configure --enable-languages=c,c++,f77,java --enable-libgcj --enable-threads=posix --with-system-zlib --enable-nls --without-included-gettext --enable-interpreter --disable-sjlj-exceptions --disable-version-specific-runtime-libs --enable-shared --enable-haifa --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --includedir=/nonexistent/include --libexecdir=/usr/sbin
Thread model: posix
gcc version 3.2.2
[1]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
[2]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
test.cpp: In constructor `C<V>::C(A<V::X>) [with V = E]':
test.cpp:28: instantiated from here
test.cpp:9: no matching function for call to `A<int>::f(A<E>::B<int>)'
test.cpp:4: candidates are: void A<T>::f(A<T>::B<int>) [with T = int]
[3]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
test.cpp: In constructor `D<V>::D(A<V::X>*) [with V = E]':
test.cpp:29: instantiated from here
test.cpp:14: no matching function for call to `A<int>::f(A<E>::B<int>)'
test.cpp:4: candidates are: void A<T>::f(A<T>::B<int>) [with T = int]
[4]
c:\cygwin\home\Christopher Colby\df>g++ test.cpp
g++ test.cpp
test.cpp: In constructor `D<V>::D(A<V::X>*) [with V = E]':
test.cpp:30: instantiated from here
test.cpp:14: no matching function for call to `A<int>::f(A<E>::B<int>)'
test.cpp:4: candidates are: void A<T>::f(A<T>::B<int>) [with T = int]
*/