This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]