Page 1 of 1

iterator for a container<Generic> is deprecated...

Posted: Wed May 10, 2006 6:55 pm
by beloni
hello, please take a look at my simple example and my compilation warnings...
can you tell me why???
program.cpp

Code: Select all


#include <iostream>
#include <vector>

using namespace std;


template<class Gen>
void printv( const vector<Gen> &somev )
{
	for( vector<Gen>::const_iterator e = somev.begin(); e != somev.end(); e++ )
		cout << *e << ", ";
}


int main()
{
	vector<double> dv( 5, 2.2 );
	vector<string> sv( 4, "I love C++" );

	printv<double>( dv );
	cout << endl;

	printv<string>( sv );
	cout << endl;

	return 0;
}
compilation warnings

beloni@weathered:~/programming/c++/tests$ g++ iterator_for_template.cpp -o iterator_for_template -O2
iterator_for_template.cpp: In function `void printv(const std::vector<Gen,
std::allocator<_CharT> >&)':
iterator_for_template.cpp:11: warning: `std::vector<Gen, std::allocator<_CharT>
>::const_iterator' is implicitly a typename
iterator_for_template.cpp:11: warning: implicit typename is deprecated, please
see the documentation for details
beloni@weathered:~/programming/c++/tests$
thanks

Posted: Wed May 10, 2006 7:24 pm
by Krzysztof Duleba
It shouldn't even compile.

Read messages from the compiler - they say everything.

When the compiler is processing a template, it doesn't know whether a class member (vector<Gen>::const_iterator) is a type or not. You should give it a hint using "typename" keyword before the type name.

Posted: Thu Jun 22, 2006 6:08 pm
by beloni
thank you very much...
but which cases vector<Gen>::iterator wont be a type ??

Posted: Thu Jun 22, 2006 7:05 pm
by Krzysztof Duleba
When vector is std::vector - never. But the compiler is processing the template first, before any instance is actually created and it's that moment when it doesn't know what to do.

Code: Select all

#include <iostream>
#include <vector>

using namespace std;

template<class Gen>
void printv( const vector<Gen> &somev ){
   for(vector<Gen>::const_iterator e = somev.begin(); e != somev.end(); e++ )
      cout << *e << ", ";
}

int main(){
} 
is, from the standpoint of compiler, not really that different than

Code: Select all

#include <iostream>
#include <vector>

using namespace std;

template<class T>
void printv( const T &somev ){
   for(T::const_iterator e = somev.begin(); e != somev.end(); e++ )
      cout << *e << ", ";
}

int main(){
} 
The compiler doesn't like the idea that type T could have const_iterator member or method instead of a typedef.

Posted: Thu Jun 22, 2006 7:14 pm
by Krzysztof Duleba
Actually, vectors can have a const_interator non-typedef member:

Code: Select all

#include <iostream>
#include <vector>

using namespace std;

template<class T>
void printv(const vector<T> &somev ){
   for(/*typename*/vector<T>::const_iterator e = somev.begin(); e != somev.end(); ++e)
      cout << *e << ", ";
}

template<typename T>
struct foovector : public vector<T>{
	int const_iterator;//!!!
};

int main(){
	foovector<int> fv;
	fv.push_back(2);
	fv.push_back(5);
	printv(fv);
} 
Look at how compiler errors change when you comment out const_iterator declaration. If typename is uncommended, everything works smoothly (the compiler will know to look for const_iterator typedef and ignore other members).