Avoiding ugly template pedantry

  • Thread starter Frederick Gotham
  • Start date
F

Frederick Gotham

I have a typedef in a base class, and I want it to effortlessly filter
through to the derived class. Here's a quick example:


class Base {
public:

typedef unsigned SpecialType;

};


class Derived : public Base {
public:

SpecialType obj;

};


int main()
{
Derived obj;

obj.obj = 7;
}


This works perfectly. However, if I bring templates into the equation,
the following doesn't compile:

template<class T>
class Base {
public:

typedef unsigned SpecialType;

};

template<class T>
class Derived : public Base<T> {
public:

SpecialType obj;

};


int main()
{
Derived<int> obj;

obj.obj = 7;
}


Instead, I have to write:


template<class T>
class Base {
public:

typedef unsigned SpecialType;

};

template<class T>
class Derived : public Base<T> {
public:

typename Base<T>::SpecialType obj;

};


int main()
{
Derived<int> obj;

obj.obj = 7;
}


Things get really ugly when I've got a lot of templates; here's the
signature of a function I wrote recently:

template<class T, class U>
const typename Arb<T,U>::SpecialType* Arb<T,U>::Func();


Is there any way nice way to avoid this ugliness? Are there any proposals
(other than templated namespaces) to simplify this stuff? For instance,
in the same fashion as "Koenig look-up", I think the previous function
declaration should be able to be written as:

template<class T, class U>
const SpecialType* Arb<T,U>::Func();


Or perhaps even:


const SpecialType *Arb::Func();


I'm writing code at the moment which is VERY heavy on nested templates,
and things are getting quite ugly. I'm running out of horizontal screen
space very quickly.
 
A

Alf P. Steinbach

* Frederick Gotham:
[snip]
Instead, I have to write:

template<class T>
class Base {
public:

typedef unsigned SpecialType;

};

template<class T>
class Derived : public Base<T> {
public:

typename Base<T>::SpecialType obj;

};

How about

template<class T>
class Derived : public Base<T> {
public:
typedef Base<T> Super; // Just in case lots of templ.args.
typedef typename Super::SpecialType SpecialType;
SpecialType obj;
};
 
C

Cy Edmunds

Frederick Gotham said:
I have a typedef in a base class, and I want it to effortlessly filter
through to the derived class. Here's a quick example:


class Base {
public:

typedef unsigned SpecialType;

};


class Derived : public Base {
public:

SpecialType obj;

};


int main()
{
Derived obj;

obj.obj = 7;
}


This works perfectly. However, if I bring templates into the equation,
the following doesn't compile:

template<class T>
class Base {
public:

typedef unsigned SpecialType;

};

template<class T>
class Derived : public Base<T> {
public:

SpecialType obj;

};


int main()
{
Derived<int> obj;

obj.obj = 7;
}

The above code worked fine for me.
Instead, I have to write:


template<class T>
class Base {
public:

typedef unsigned SpecialType;

};

template<class T>
class Derived : public Base<T> {
public:

typename Base<T>::SpecialType obj;

};


int main()
{
Derived<int> obj;

obj.obj = 7;
}


Things get really ugly when I've got a lot of templates; here's the
signature of a function I wrote recently:

template<class T, class U>
const typename Arb<T,U>::SpecialType* Arb<T,U>::Func();


Is there any way nice way to avoid this ugliness? Are there any proposals
(other than templated namespaces) to simplify this stuff? For instance,
in the same fashion as "Koenig look-up", I think the previous function
declaration should be able to be written as:

template<class T, class U>
const SpecialType* Arb<T,U>::Func();


Or perhaps even:


const SpecialType *Arb::Func();


I'm writing code at the moment which is VERY heavy on nested templates,
and things are getting quite ugly. I'm running out of horizontal screen
space very quickly.

Why doesn't it compile? It works OK for me on VC7. What message do you get?
And what compiler are you using?

Cy
 
A

Alf P. Steinbach

* Cy Edmunds:
Why doesn't it compile? It works OK for me on VC7. What message do you get?
And what compiler are you using?

I'm guessing g++ for Windows; that was the basis of my reply elsethread.
 
F

Frederick Gotham

Cy Edmunds posted:
The above code worked fine for me.


I'm using g++ in combination with Dev-C++, and I get a compile error. The
compiler even gives me a hint:

"Perhaps you meant: typename Base<T>::SpecialType"


According to the Standard, should the code compile? I'm going to do two
things:

(1) Update g++
(2) Ask over on comp.std.c++ if it should compile
 
T

Tom Widmer

Frederick said:
Cy Edmunds posted:





I'm using g++ in combination with Dev-C++, and I get a compile error. The
compiler even gives me a hint:

"Perhaps you meant: typename Base<T>::SpecialType"


According to the Standard, should the code compile? I'm going to do two
things:

(1) Update g++
(2) Ask over on comp.std.c++ if it should compile

You need only do that if no one can answer you here. But of course,
typename is required wherever you name a type that is a dependent name,
as in the examples you presented. Some older compilers are permissive
about this, since they don't support "two phase name lookup". IIRC GCC
3.4 and later supports it.

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top