This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
g++ rejects legal?
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 4 Nov 2004 13:22:35 +0100 (CET)
- Subject: g++ rejects legal?
Hi!
There must be some weird C++ rules again. Consider:
template <int Dim, class T, class E>
class Array;
template <int Dim, class T, class ET>
struct Engine;
template <int Dim>
struct Loc;
template <class E, class C>
struct CompFwd;
template <int Dim, class T, class E, class C>
struct Engine<Dim, T, CompFwd<E, C> >;
struct Brick;
template <int Dim, class T>
struct Engine<Dim, T, Brick>;
template <class Components, class Subject>
struct ComponentView;
template <class Components, class Subject>
struct AltComponentView;
template<class Components, int Dim, class T, class EngineTag>
struct ComponentView<Components, Array<Dim, T, EngineTag> >
{
// Convenience typedef for the thing we're taking a component view of.
typedef Array<Dim, T, EngineTag> Subject_t;
// Deduce the template parameters for the output type.
typedef typename Subject_t::Element_t Element_t;
typedef typename Subject_t::Engine_t Engine_t;
typedef CompFwd<Engine_t, Components> NewEngineTag_t;
// The output type.
typedef Array<Dim, Element_t, NewEngineTag_t> Type_t;
};
template<class Components, int Dim, class T, class EngineTag>
struct AltComponentView<Components, Array<Dim, T, EngineTag> >
{
// Convenience typedef for the thing we're taking a component view of.
typedef Array<Dim, T, EngineTag> Subject_t;
// Deduce the template parameters for the output type.
typedef typename Subject_t::Element_t Element_t;
typedef typename Subject_t::Engine_t Engine_t;
typedef CompFwd<Engine_t, Components> NewEngineTag_t;
// The output type.
typedef Array<Dim, Element_t, NewEngineTag_t> Type_t;
};
template <int Dim, class T, class EngineTag>
class Array
{
public:
typedef Engine<Dim, T, EngineTag> Engine_t;
typedef Array<Dim, T, EngineTag> This_t;
typedef T Element_t;
Array() {}
inline typename ComponentView<Loc<1>, This_t>::Type_t
comp(int i1) const;
};
and now a simple function:
void foo(void)
{
typedef Array<1, double, Brick> Array_t;
typedef ComponentView<Loc<1>, Array_t>::Type_t CView_t;
}
triggers (g++ 3.4 and mainline):
notype.cpp: In instantiation of 'Array<1, double, Brick>':
notype.cpp:33: instantiated from `ComponentView<Loc<1>, foo()::Array_t>'
notype.cpp:78: instantiated from here
notype.cpp:71: error: no type named 'Type_t' in 'struct
ComponentView<Loc<1>, foo()::Array_t>'
now, trying
void foo(void)
{
typedef Array<1, double, Brick> Array_t;
typedef AltComponentView<Loc<1>, Array_t>::Type_t CView_t;
}
noting that we now use AltComponentView instead of ComponentView,
noting that there is no difference between both, compilation of
foo() succeds. Even more weird, doing
void foo(void)
{
typedef Array<1, double, Brick> Array_t;
typedef AltComponentView<Loc<1>, Array_t>::Type_t CView_t;
typedef ComponentView<Loc<1>, Array_t>::Type_t CView2_t;
}
succeeds, too, swapping the two typedefs fails again. The errors
can be avoided, too, by removing the declaration of Array::comp(int).
I am totally confused here. Of course, the Intel compiler behaves exactly
the same!
Thanks for any hint,
Richard.
--
Richard Guenther <richard dot guenther at uni-tuebingen dot de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/