469,934 Members | 2,534 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,934 developers. It's quick & easy.

implicit type template warning

Hi

Can somebody explain to me why I get this warning message and how I
can solve this warning message.

Thanks a lot

Johan

In member function `void
Callback1<Par>::search()':
b.cpp:44: warning: `typename std::vector<Callback<Par>,
std::allocator<Callback<Par> > >::iterator' is implicitly a
typename
b.cpp:44: warning: implicit typename is deprecated, please see the
documentation for details
template <class Par>
class Callback
{
public :
Callback(const Par& par) : par(par)
{
}
~Callback()
{
}

void show()
{
cout << par << endl;
}

private :
Par par;
};
template <class Par>
class Callback1 : public Callback<Par>
{
public :
typedef Callback< Par > CallbackPar;

Callback1(const Par& par) : Callback<Par>(par)
{
v.push_back(par);
}
~Callback1()
{
}

void search()
{
vector< Callback< Par > >::iterator i;
}

private :
vector< Callback< Par > > v;
};

b.cpp: In member function `void Callback1<Par>::search()':
b.cpp:44: warning: `typename std::vector<Callback<Par>,
std::allocator<Callback<Par> > >::iterator' is implicitly a
typename
b.cpp:44: warning: implicit typename is deprecated, please see the
documentation for details
Jul 22 '05 #1
11 1680

Johan wrote:
Hi

Can somebody explain to me why I get this warning message and how I
can solve this warning message. In member function `void
Callback1<Par>::search()':
b.cpp:44: warning: `typename std::vector<Callback<Par>,
std::allocator<Callback<Par> > >::iterator' is implicitly a
typename
b.cpp:44: warning: implicit typename is deprecated, please see the
documentation for details .... template <class Par>
class Callback1 : public Callback<Par> {
void search() {
vector< Callback< Par > >::iterator i;


Sure. What kind of name is iterator, a template, a variable, or a type
(enum/typedef/nested class)? The compiler will know this only when it
knows what Par is, but when the template is compiled this isn't yet
known. Par will be provided later during instantiation.

The warning tells you that the compiler guessed, and it guessed
correctly. iterator is a typename. To prevent the warning, be
explicit and put the typename in yourself.
BTW, the warning said "RTFM", didn't it include this?
Regards,
Michiel Salters

Jul 22 '05 #2

"msalters" <Mi*************@logicacmg.com> wrote in message news:11*********************@c13g2000cwb.googlegro ups.com...

Johan wrote:
Hi

Can somebody explain to me why I get this warning message and how I
can solve this warning message.

In member function `void
Callback1<Par>::search()':
b.cpp:44: warning: `typename std::vector<Callback<Par>,
std::allocator<Callback<Par> > >::iterator' is implicitly a
typename
b.cpp:44: warning: implicit typename is deprecated, please see the
documentation for details

...
template <class Par>
class Callback1 : public Callback<Par> {
void search() {
vector< Callback< Par > >::iterator i;


Sure. What kind of name is iterator, a template, a variable, or a type
(enum/typedef/nested class)? The compiler will know this only when it
knows what Par is, but when the template is compiled this isn't yet
known. Par will be provided later during instantiation.

The warning tells you that the compiler guessed, and it guessed
correctly. iterator is a typename. To prevent the warning, be
explicit and put the typename in yourself.


So,
typename vector< Callback< Par > >::iterator i;

Can something else be instead of 'typename'?

[snip]
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn


Jul 22 '05 #3
Alex Vinokur wrote:
So,
typename vector< Callback< Par > >::iterator i;

Can something else be instead of 'typename'?


If you don't include 'typename' the compiler has to assume that it
is a value. For standard classes this may seem to be unreasable
because you have a hard time to get something else than a type
without violating some other rule but the same rule applies here
as to user defined types. For these it is pretty easy to have a
value or a type in a context and the compiler could, without the
typename, only detect the correct meaning at instantiation type.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 22 '05 #4

"Dietmar Kuehl" <di***********@yahoo.com> wrote in message news:11*********************@f14g2000cwb.googlegro ups.com...
Alex Vinokur wrote:
So,
typename vector< Callback< Par > >::iterator i;

Can something else be instead of 'typename'?


If you don't include 'typename' the compiler has to assume that it
is a value.
For standard classes this may seem to be unreasable
because you have a hard time to get something else than a type
without violating some other rule but the same rule applies here
as to user defined types. For these it is pretty easy to have a
value or a type in a context and the compiler could, without the
typename, only detect the correct meaning at instantiation type.

[snip]

------ foo.cpp ------
#include <vector>
using namespace std;

template <typename T>
struct Foo
{
vector<int>::iterator iter1;
typename vector<T>::iterator iter2;
};

int main()
{
Foo<double> f;
return 0;
}
---------------------

Is iter1 a value?
Is iter2 a typename?
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn


Jul 22 '05 #5
Alex Vinokur wrote:
template <typename T>
struct Foo
{
vector<int>::iterator iter1;
typename vector<T>::iterator iter2;
};

int main()
{
Foo<double> f;
return 0;
}
---------------------

Is iter1 a value?
Is iter2 a typename?


You mean, I failed to mention that 'typename' is only necessary
if it applies to a dependent name? (and currently prohbited if
not necessary; it is discussed to change the latter rule) Fair
enough: both 'iter1' and 'iter2' are type names because 'iter1'
does not depend on a template parameter and it is guaranteed to
the compiler that 'iter2' is indeed a type name.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 22 '05 #6
Dietmar Kuehl wrote:
Alex Vinokur wrote:
template <typename T>
struct Foo
{
vector<int>::iterator iter1;
typename vector<T>::iterator iter2;
};

int main()
{
Foo<double> f;
return 0;
}
---------------------

Is iter1 a value?
Is iter2 a typename?

You mean, I failed to mention that 'typename' is only necessary
if it applies to a dependent name? (and currently prohbited if
not necessary; it is discussed to change the latter rule) Fair
enough: both 'iter1' and 'iter2' are type names because 'iter1'
does not depend on a template parameter and it is guaranteed to
the compiler that 'iter2' is indeed a type name.


Uh... I somehow thought that 'iter1' and 'iter2' are member names.

V
Jul 22 '05 #7

"Victor Bazarov" <v.********@comAcast.net> wrote in message news:Sy*******************@newsread1.mlpsca01.us.t o.verio.net...
Dietmar Kuehl wrote:
Alex Vinokur wrote:
template <typename T>
struct Foo
{
vector<int>::iterator iter1;
typename vector<T>::iterator iter2;
};

int main()
{
Foo<double> f;
return 0;
}
---------------------

Is iter1 a value?
Is iter2 a typename?

You mean, I failed to mention that 'typename' is only necessary
if it applies to a dependent name? (and currently prohbited if
not necessary; it is discussed to change the latter rule) Fair
enough: both 'iter1' and 'iter2' are type names because 'iter1'
does not depend on a template parameter and it is guaranteed to
the compiler that 'iter2' is indeed a type name.


Uh... I somehow thought that 'iter1' and 'iter2' are member names.

V


It seems that _iterators_ in 'vector<int>::iterator' and 'typename vector<T>::iterator' are type names (?).

--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn



Jul 22 '05 #8
Alex Vinokur wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Sy*******************@newsread1.mlpsca01.us.t o.verio.net...
Dietmar Kuehl wrote:
Alex Vinokur wrote:
template <typename T> struct Foo { vector<int>::iterator iter1;
typename vector<T>::iterator iter2; };

int main() { Foo<double> f; return 0; } ---------------------

Is iter1 a value? Is iter2 a typename?
You mean, I failed to mention that 'typename' is only necessary if
it applies to a dependent name? (and currently prohbited if not
necessary; it is discussed to change the latter rule) Fair enough:
both 'iter1' and 'iter2' are type names because 'iter1' does not
depend on a template parameter and it is guaranteed to the compiler
that 'iter2' is indeed a type name.


Uh... I somehow thought that 'iter1' and 'iter2' are member names.

V

It seems that _iterators_ in 'vector<int>::iterator' and 'typename
vector<T>::iterator' are type names (?).


Yes, they are. And it doesn't just seem so, it _is_ so. I was simply
surprised by the use of <<'iter1'>> and <<'iter2'>> in Dietmar's reply.

V
Jul 22 '05 #9

"Victor Bazarov" <v.********@comAcast.net> wrote in message news:4W*******************@newsread1.mlpsca01.us.t o.verio.net...
Alex Vinokur wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:Sy*******************@newsread1.mlpsca01.us.t o.verio.net...
Dietmar Kuehl wrote:

Alex Vinokur wrote:
> template <typename T> struct Foo { vector<int>::iterator iter1;
> typename vector<T>::iterator iter2; };
>
> int main() { Foo<double> f; return 0; } ---------------------
>
> Is iter1 a value? Is iter2 a typename?
You mean, I failed to mention that 'typename' is only necessary if
it applies to a dependent name? (and currently prohbited if not
necessary; it is discussed to change the latter rule) Fair enough:
both 'iter1' and 'iter2' are type names because 'iter1' does not
depend on a template parameter and it is guaranteed to the compiler
that 'iter2' is indeed a type name.

Uh... I somehow thought that 'iter1' and 'iter2' are member names.

V

It seems that _iterators_ in 'vector<int>::iterator' and 'typename
vector<T>::iterator' are type names (?).


Yes, they are. And it doesn't just seem so, it _is_ so. I was simply
surprised by the use of <<'iter1'>> and <<'iter2'>> in Dietmar's reply.

V

Here are a sample connected to the issue.

------ file.cpp ------
struct Foo
{
struct Bar {};
static void foo (int) {}
static int data;
};
int Foo::data(0);

template <typename T>
struct Blah
{
Foo::Bar b1; // 'Bar' is explicit type name, b1 is value
Foo::Bar (b2); // 'Bar' is explicit type name, b2 is value

// T::Bar b3; // 'Bar' is implicit type name
// T::Bar (b4); // 'Bar' is implicit type name

typename T::Bar b3; // Now 'Bar' is explicit type name, b3 is value
typename T::Bar (b4); // Now 'Bar' is explicit type name, b4 is value

void blah1 () { int x(0); T::foo(x); } // 'foo' is explicit function name
void blah2 () { T::data; } // 'data' is explicit value name

// ----------------------
void blah3 (Foo::Bar, typename T::Bar, void (*)(int), int) {}
// 'Bar' in Foo::Bar is explicit type name
// 'Bar' in T::Bar is now explicit type name
// ----------------------
};

int main()
{
Foo::Bar bar;

Blah<Foo> blah;

// ---------
blah.blah1();

blah.blah2();
// ---------

// ----------------------------------------
blah.blah3 (bar, bar, Foo::foo, Foo::data);
// 'foo' is explicit function name
// 'data' is explicit value name
// ----------------------------------------

return 0;
}

----------------------

See also http://www.glenmccl.com/ansi_035.htm .
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn


Jul 22 '05 #10
Victor Bazarov wrote:
Dietmar Kuehl wrote:
Alex Vinokur wrote:
template <typename T>
struct Foo
{
vector<int>::iterator iter1;
typename vector<T>::iterator iter2;
};

int main()
{
Foo<double> f;
return 0;
}
---------------------

Is iter1 a value?
Is iter2 a typename?

You mean, I failed to mention that 'typename' is only necessary
if it applies to a dependent name? (and currently prohbited if
not necessary; it is discussed to change the latter rule) Fair
enough: both 'iter1' and 'iter2' are type names because 'iter1'
does not depend on a template parameter and it is guaranteed to
the compiler that 'iter2' is indeed a type name.


Uh... I somehow thought that 'iter1' and 'iter2' are member names.


Stupid me: spreading more confusion than knowledge! Of course, both
are member names. I apparently got confused by the question...

The reason why 'typename' is required when using dependent names is
that there are contexts where an ambiguity between a type and a
variable can occur. The typical example is something like this:

int foo = 0;
template <typename T> struct bar { static int const type = 0; };
template <> struct bar<int> { typedef int type; } // stupid...

template <typename T> void f() {
bar<int>::type* f; // pointer declaration
bar<T>::type * foo; // useless multiplication
}

The second statement in 'f()'s body is considered to be a
multiplication, even when instantiated with type 'int' in which
case it would cause a compiler error: 'bar<T>::type' depends on a
template parameter and is thus a dependent name. Dependend names
are considered to be objects unless qualified by 'typename'.
Non-dependent names, like 'bar<int>::type' can be immediately
deduced, i.e. there is no need to wait until instantiation to
find out that it is actually a type.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
Jul 22 '05 #11

"Dietmar Kuehl" <di***********@yahoo.com> wrote in message news:35*************@individual.net...
Victor Bazarov wrote:
Dietmar Kuehl wrote:
Alex Vinokur wrote:

template <typename T>
struct Foo
{
vector<int>::iterator iter1;
typename vector<T>::iterator iter2;
};

int main()
{
Foo<double> f;
return 0;
}
---------------------

Is iter1 a value?
Is iter2 a typename?
You mean, I failed to mention that 'typename' is only necessary
if it applies to a dependent name? (and currently prohbited if
not necessary; it is discussed to change the latter rule) Fair
enough: both 'iter1' and 'iter2' are type names because 'iter1'
does not depend on a template parameter and it is guaranteed to
the compiler that 'iter2' is indeed a type name.
Uh... I somehow thought that 'iter1' and 'iter2' are member names.


Stupid me: spreading more confusion than knowledge! Of course, both
are member names. I apparently got confused by the question...


Sorry, my question was incorrectly formulated.

The reason why 'typename' is required when using dependent names is
that there are contexts where an ambiguity between a type and a
variable can occur. The typical example is something like this:

int foo = 0;
template <typename T> struct bar { static int const type = 0; };
template <> struct bar<int> { typedef int type; } // stupid...

template <typename T> void f() {
bar<int>::type* f; // pointer declaration
bar<T>::type * foo; // useless multiplication
}

The second statement in 'f()'s body is considered to be a
multiplication, even when instantiated with type 'int' in which
case it would cause a compiler error: 'bar<T>::type' depends on a
template parameter and is thus a dependent name. Dependend names
are considered to be objects unless qualified by 'typename'.
Non-dependent names, like 'bar<int>::type' can be immediately
deduced, i.e. there is no need to wait until instantiation to
find out that it is actually a type.

[snip]

g++ 3.3 accepts a code below.
g++ 3.4 rejects it.

------ file.cpp ------
int foo = 0;

template <typename T> struct bar { static int const type = 0; };
template <> struct bar<int> { typedef int type; };

template <typename T> void f()
{
bar<int>::type* ptr; // pointer declaration
bar<T>::type * foo; // useless multiplication // Line#9
typename bar<T>::type * bar; // now explicit type name
}

int main()
{
int i = bar<double>::type * foo;

f<int>(); // Line#17

return 0;
}
----------------------
--- Compilation ---

// gpp.exe (GCC) 3.4.1

$ gpp file.cpp

file.cpp: In function `void f() [with T = int]':
file.cpp:17: instantiated from here
file.cpp:9: error: dependent-name `bar<T>::type' is parsed as a non-type, but instantiation yields a type
file.cpp:9: note: say `typename bar<T>::type' if a type is meant

-------------------

--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 22 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Steve Hill | last post: by
1 post views Thread by Marcin Kalicinski | last post: by
3 posts views Thread by Šimon Tóth | last post: by
1 post views Thread by lutorm | last post: by
1 post views Thread by pmatos | last post: by
15 posts views Thread by buda | last post: by
8 posts views Thread by xuatla | last post: by
18 posts views Thread by Tony | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.