tags:

views:

64

answers:

1

in the following code:

int utf8len(char* s, int len)
{
 Glib::ustring::iterator p( string::iterator(s) );
 Glib::ustring::iterator e ( string::iterator(s+len) );
 int i=0;
    for (; p != e; p++) // ERROR HERE!
  i++;
 return i;
}

I get the compiler error on the for line, which is sometimes "invalid lvalue in increment", and sometimes "ISO C++ forbids incrementing a pointer of type etc... ".

Yet, the follwing code:

int utf8len(char* s)
{
 Glib::ustring us(s);
 int i=0;
    for (Glib::ustring::iterator p = us.begin(); p != us.end(); p++)
  i++;
 return i;

}

compiles and works fine.

according the Glib::ustring documentation and the include file, ustring iterator can be constructed from std::string iterator, and has operator++() defined. Weird?

---EDIT---

It gets "Curiouser and curiouser"! this code

int utf8len(string::iterator s, string::iterator e)
{
    Glib::ustring::iterator p(s);
    Glib::ustring::iterator end(e);
    int i=0;
    for (; p != end; p++)
        i++;
    return i;
}

compiles and works fine.

---EDIT---

BONUS QUESTION :)

Is there a difference in C++ between the 2 ways of defining a variable:

  classname ob1( initval );
  classname ob1 = initval;

I believed that they are synonymous; yet, if I change

   Glib::ustring::iterator p( string::iterator(s) );

to

 Glib::ustring::iterator p = string::iterator(s);

I get a compiler error (gcc 4.1.2)

conversion from ‘__gnu_cxx::__normal_iterator, std::allocator > >’ to non-scalar type ‘Glib::ustring_Iterator<__gnu_cxx::__normal_iterator, std::allocator > > >’ requesed

thanks a lot!

+3  A: 

Your declaration declares this function:

Glib::ustring::iterator p(string::iterator s);

The parentheses in your code around s are ignored. They are like the parentheses around n in the following example

int(n);
n = 0; /* n is actually an int variable! */

They are for grouping modifiers like pointer (*) or references (&) (think about void(*fptr)()). In your case the parentheses are just semantically redundant.

Try this one instead:

Glib::ustring::iterator p( (string::iterator(s)) );

The parentheses introduced make the compiler regognize that it should instead construct an object p initialized from an expression (because a function parameter declaration can't have parentheses around it, it's not parsed as a parameter declaration, but instead as an initializer).

Johannes Schaub - litb
Thanks a lot! why wouldn't the version "Glib::ustring::iterator p = string::iterator(s);" work, though? Seems that it does not have this ambiguity.
davka
@davka in an initialization, only one user defined conversion is allowed and in that form only non-explicit copy constructors are used. Any of these two facts could cause the compile error.
Johannes Schaub - litb
thanks a lot again
davka