Subtypes of templated types (in templated functions)

M

Marijn

I recently told g++ (3.2) something to the effect of:

template <class T>
struct test{
typedef int type;
};

template <class T>
void f(){
test<T>::type i;
}

To which g++ responded (in an unfriendly manner):

test.cpp: In function 'void f()':
test.cpp:11: warning: 'typename test<T>::type' is implicitly a
typename
test.cpp:11: warning: implicit typename is deprecated, please see the
documentation for details

Which confused me quite a lot. "test<T>::type" look explicit enough to
me... it only seems to happen when both the class and the function are
templates, and I can declare a test<T> allright, just not a
test<T>::type. Is this a language problem? I do not have any other
compilers so I do not know whether it could be a compiler thingy.
Suffice to say, it annoys me, I was trying to use a std::vector's
iterators in a templated container class that used an internal vector,
and it just would not allow it.

Marijn Haverbeke
 
P

Patrik Stellmann

template <class T>
void f(){
test<T>::type i;
}

To which g++ responded (in an unfriendly manner):

test.cpp: In function 'void f()':
test.cpp:11: warning: 'typename test<T>::type' is implicitly a
typename
test.cpp:11: warning: implicit typename is deprecated, please see the
documentation for details
Just a guess but probably the compiler simply tries to tell you that you
should write
typename test<T>::type i;
 
J

John Harrison

Marijn said:
I recently told g++ (3.2) something to the effect of:

template <class T>
struct test{
typedef int type;
};

template <class T>
void f(){
test<T>::type i;
}

To which g++ responded (in an unfriendly manner):

test.cpp: In function 'void f()':
test.cpp:11: warning: 'typename test<T>::type' is implicitly a
typename
test.cpp:11: warning: implicit typename is deprecated, please see the
documentation for details

Which confused me quite a lot. "test<T>::type" look explicit enough to
me... it only seems to happen when both the class and the function are
templates, and I can declare a test<T> allright, just not a
test<T>::type.

The compiler cannot know that test<T>::type is a typename and not a static
data member when it is compiling f(), since at that point it does not know
the type of T, and it does not know what template specialisations of test<T>
might exist. Or something like that, any corrections or clarifications
welcome.
Is this a language problem?

It a requirement of the language that you say

typename test<T>::type i;

in this situation. Its arguably a language problem since it seems this
ambiguity (and a few others) were not appreciated when templates where added
informally to the language, typename got added later when this became known.
I do not have any other
compilers so I do not know whether it could be a compiler thingy.
Suffice to say, it annoys me, I was trying to use a std::vector's
iterators in a templated container class that used an internal vector,
and it just would not allow it.

All you have to do is add typename, in the appropriate places.
Marijn Haverbeke

john
 
C

Christian Jaeger

Well, I was thought that for templates, it makes sense to explicitly
specify, wheter something is to be considered as a type or a non-type.
Maybe the following example is helpful:


struct foo{
typedef int t;
};

struct bar{
static const int t=10;
};

int m = 10;

template <typename T> void f(){
T::t* m; // declaration of an int* (for foo),
// or multiplication (for bar)
}

int main(){
f<foo>();
f<bar>();
}
 
S

Sharad Kala

Marijn said:
I recently told g++ (3.2) something to the effect of:

template <class T>
struct test{
typedef int type;
};

template <class T>
void f(){
test<T>::type i;
}

To which g++ responded (in an unfriendly manner):

test.cpp: In function 'void f()':
test.cpp:11: warning: 'typename test<T>::type' is implicitly a
typename
test.cpp:11: warning: implicit typename is deprecated, please see the
documentation for details

Which confused me quite a lot. "test<T>::type" look explicit enough to
me... it only seems to happen when both the class and the function are
templates, and I can declare a test<T> allright, just not a
test<T>::type. Is this a language problem? I do not have any other
compilers so I do not know whether it could be a compiler thingy.
Suffice to say, it annoys me, I was trying to use a std::vector's
iterators in a templated container class that used an internal vector,
and it just would not allow it.

Consider test<T>::type* i;
May be your intention was to declare i as a pointer but compiler could take it
for a multiplication.
Hence the need of typename is needed in case of dependent names to tell that
what follows is a type.
Josuttis/Vandevoorde cover dependent names etc in good detail in Part II of
their book "C++ Templates".

Also it's worth to read what Herb Sutter has to say in this article -
http://www.gotw.ca/gotw/035.htm

-Sharad
 
M

Marijn

All you have to do is add typename, in the appropriate places.

Ahh okay. Thanks for the clarification. I think C++ is the only
language that keeps surprising me after 4 years of using it.

Marijn Haverbeke
 

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

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top