various problems with template-name template parameters
Ewgenij Gawrilow
gawrilow@math.TU-Berlin.DE
Wed Mar 1 06:29:00 GMT 2000
I've brought several code fragments together, because I thought they are
hitting various bugs in the same corner of the C++ front-end. If I'm in error,
please split the test suite accordingly and excuse me for causing this extra work.
System environment as follows:
% uname -a
SunOS sokol 5.7 Generic_106541-08 sun4u sparc SUNW,UltraSPARC-IIi-Engine
% g++ -v
Using builtin specs.
gcc version 2.95.2 19991024 (release)
% cat tmp/gcc-build/config.status
#!/bin/sh
# This file was generated automatically by configure. Do not edit.
# This directory was configured as follows:
.../tmp/gcc-2.95.2/configure --with-gcc-version-trigger=.../tmp/gcc-2.95.2/gcc/version.c --host=sparc-sun-solaris2.6 --enable-shared --enable-version-specific-runtime-libs --enable-languages=c++ --with-gxx-include-dir=/usr/local/include/C++ --norecursion
# using "mh-frag" and "mt-frag"
********************************************************************************
The actual value of the template-name argument of a member template
gets "spilled" when passed to another template instantiation:
#line 1 "prob4.cc"
template <class T>
struct Op { };
template <template <class X> class Y>
void g() { }
template <class T>
class A {
public:
template <template <class X> class Y>
void f() {
g<Y>();
}
};
int main() {
A<int> a;
a.template f<Op>();
return 0;
}
prob4.cc: In instantiation of `g<Y>()':
prob4.cc:12: instantiated from here
prob4.cc:5: Internal compiler error.
********************************************************************************
Here the wrong specialization is being chosen.
#include <iostream>
template <template <class X> class B, class A>
struct is_instance_of {
enum { answer=false };
};
template <template <class X> class B, class T>
struct is_instance_of<B, B<T> > {
enum { answer=true };
};
template <class X> struct C { };
template <class X> struct D { };
template <class T>
bool is_C (const T&) {
return is_instance_of<C,T>::answer;
};
int main() {
cout << "should be true: " << is_C(C<int>()) << endl;
cout << "should be false: " << is_C(D<int>()) << endl;
return 0;
}
The program prints:
should be true: 1
should be false: 1
********************************************************************************
This test case has remained rather long despite of all my trying to strip off
all unnecessary details. Sorry.
#line 1 "prob6.cc"
template <class X, class Y>
class A : public X { };
struct B { };
template <template <class XX, class YY> class Z, class X, class Y>
class C { };
template <class X>
class D { };
template <class X, class Y>
class E : public D<typename X::I> {
public:
E(const X&, const Y&) { }
};
class F {
public:
typedef int I;
};
template <class X, class Y>
class G {
public:
typedef A<X, C<E,F,Y> > R;
R r() const;
};
class H {
public:
bool operator== (const H& i2) const;
};
void f()
{
G<H,B> g1, g2;
g1.r() == g2.r();
}
prob6.cc: In function `void f()':
prob6.cc:38: Internal compiler error 390.
********************************************************************************
I'm not that sure about the last problem, whether it's caused by a compiler bug
or just by my imperfect understanding of C++. Although I haven't found the
passage in the Standard explicitly prohibiting the following construction:
#line 1 "prob7.cc"
template <template <class X> class Y>
class A {
public:
template <class T> class B { };
};
class A2 {
public:
template <class T> class B { };
};
template <class T> class C { };
template <template <class X> class Y> class D { };
template <template <class X> class Y> void f(int);
void g() {
D<C> d1;
f<C>(0);
A<C>::B<int> a1;
A2::B<int> a2;
D<A2::B> d2;
f<A2::B>(0);
D<A<C>::B> d3;
f<A<C>::B>(0);
};
prob7.cc: In function `void g()':
prob7.cc:23: Internal compiler error 980422.
********************************************************************************
With best regards,
Ewgenij Gawrilow
Dept. of Mathematics, Technical University of Berlin
More information about the Gcc-bugs
mailing list