Archived

This topic is now archived and is closed to further replies.

iamjoesname

g++ string::iterator error

Recommended Posts

iamjoesname    122
Hey guys...having a bit of problem with g++ 3.2.2 using the following code:
string CApp::ToLowerCase(string toLower)
{
     string::iterator it;

     // convert to lowercase

     for(it = toLower.begin(); it != toLower.end(); it++)
          toLower.replace(it, it+1, 1, tolower(*it));

     return toLower;
}
g++ chokes on the line "string::iterator it":
   
/usr/include/c++/3.2.2/bits/stl_iterator_base_types.h: In instantiation of `std::iterator_traits<int>':
/usr/include/c++/3.2.2/bits/basic_string.h:688:   instantiated from `std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT,
_Traits, _Alloc>::replace(__gnu_cxx::__normal_iterator<_Alloc::Pointer, std::basic_string<_CharT, _Traits, _Alloc> >, __gnu_cxx::__normal_iterator<_Alloc::Pointer, std::basic_string<_CharT, _Traits, _Alloc> >, _InputIterator, _InputIterator) [with _InputIterator = int, _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'
app.cpp:575:   instantiated from here
/usr/include/c++/3.2.2/bits/stl_iterator_base_types.h:123: `int' is not a
   class, struct, or union type
/usr/include/c++/3.2.2/bits/stl_iterator_base_types.h:124: `int' is not a
   class, struct, or union type
/usr/include/c++/3.2.2/bits/stl_iterator_base_types.h:125: `int' is not a
   class, struct, or union type
/usr/include/c++/3.2.2/bits/stl_iterator_base_types.h:126: `int' is not a
   class, struct, or union type
/usr/include/c++/3.2.2/bits/stl_iterator_base_types.h:127: `int' is not a
   class, struct, or union type
/usr/include/c++/3.2.2/bits/basic_string.h: In member function
   `std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT,
   _Traits, _Alloc>::replace(__gnu_cxx::__normal_iterator<_Alloc::Pointer,
   std::basic_string<_CharT, _Traits, _Alloc> >,
   __gnu_cxx::__normal_iterator<_Alloc::Pointer, std::basic_string<_CharT,
   _Traits, _Alloc> >, _InputIterator, _InputIterator) [with _InputIterator =
   int, _CharT = char, _Traits = std::char_traits<char>, _Alloc =
   std::allocator<char>]':
app.cpp:575:   instantiated from here
/usr/include/c++/3.2.2/bits/basic_string.h:688: no type named `
   iterator_category' in `struct std::iterator_traits<int>'
make: *** [main] Error 1
 
I checked the help docs at gcc's website, but found no answers. I have no trouble declaring iterators to other STL structures, just with the string class. Namespace is not an issue either. The code compiles and functions without a hitch in .NET 2003. Thanks in advance. EDIT: formatting issues [edited by - iamjoesname on March 28, 2004 9:22:36 PM]

Share this post


Link to post
Share on other sites
Sneftel    1788
What #includes and using directives do you have in that file?


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
iamjoesname    122
I am #including app.h, iostream, cctype (for the tolower() function), sstream, and fstream. string, vector, and stack are #included via app.h. My using directives are std::vector, std::string, std::cin, std::cout, std::endl, std::getline, std::istringstream, std::ifstream, and std::ofstream. The gcc help docs mention a bug in earlier versions which required string to be #included before any other STL components, but that had no effect.

EDIT: more formatting issues

[edited by - iamjoesname on March 28, 2004 9:18:19 PM]

Share this post


Link to post
Share on other sites
Ronin Magus    142
Try using typename:

typename string::iterator it;

or giving it the full name:

typename std::string::iterator it;

EDIT:

I had to use this in my (jumbled, lol) hashmap code in Dusty Engine:


//! Clear deletes all nodes from the hash vector. If the value type is a pointer, it will NOT release the pointer's memory.

void Clear()
{
typename std::vector<std::list<HashMapNode<KeyType, ValueType> > >::iterator it;

for(it = hashVector.begin(); it != hashVector.end(); ++it) {
(*it).clear();
}
}



daveandrews.org - a Christian Programmer's Weblog | Dusty Engine - a task engine using Irrlicht | Computer Guys Run the World
How to be a Programmer


[edited by - Ronin Magus on March 28, 2004 9:23:41 PM]

Share this post


Link to post
Share on other sites
SiCrane    11839
Judging from the line numbers and the errors produced, it looks like it''s not actually choking on the iterator declaration. It seems to be a template instantiation resolution error on the third parameter. Try casting the 1 to std::string::size_type. e.g.:

toLower.replace(it, it+1, (std::string::size_type)1, tolower(*it));

Share this post


Link to post
Share on other sites
Sneftel    1788
Well, that line compiles fine with my GCC 3.2.2. Of course, the replace line is rather bizarre, and doesn''t compile... why aren''t you just assigning to the (dereferenced) iterator?


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
iamjoesname    122
Sneftel: the reason for the goofy code is known as "it was late, and I was tired."

I changed it to just assign to the dereferenced iterator like you said, and no more problems. It's always interesting to see what different compilers choke on--.NET didn't have a problem with it. Anyway, thanks for the help, much appreciated.

[edited by - iamjoesname on March 28, 2004 9:29:46 PM]

Share this post


Link to post
Share on other sites
Krumble    151
If you replace the line toLower.replace ...
with

*it = tolower(*it);

it works the same and compiles with g++ for me. I''m not sure why you''re getting the error with your version, but I''m getting the same one as well using your code.

Share this post


Link to post
Share on other sites
iamjoesname    122
Krumble: thanks for the reply. That''s what I changed it to. I''m not really sure why I just didn''t do that in the first place...making things harder than they are, I suppose.

Thanks for the help, guys.

Share this post


Link to post
Share on other sites
Fruny    1658
Remember that there are two different tolower function. One coming from <cctype>, one coming from <locale> (via <ios> via any stream header). This is the source of many problems. Cast the symbol to match the prototype of the version you wish to use.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan

Share this post


Link to post
Share on other sites