не может увеличивать Glib::ustring::iterator (получение недопустимого значения lvalue при ошибке компилятора увеличения)

в следующем коде:

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;
}

Я получаю ошибку компилятора в строке for, которая иногда является «недопустимой lvalue в приращении», а иногда «ISO C++ запрещает увеличивать указатель типа и т. д.».

Тем не менее, следующий код:

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;

}

компилируется и работает нормально.

согласно документации Glib::ustring и включаемому файлу, итератор ustring может быть создан из std::string итератора и определен operator++(). Странный?

---РЕДАКТИРОВАТЬ---

Становится все страньше и страньше! этот код

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;
}

компилируется и работает нормально.

---РЕДАКТИРОВАТЬ---

БОНУСНЫЙ ВОПРОС :)

Есть ли разница в С++ между двумя способами определения переменной:

  classname ob1( initval );
  classname ob1 = initval;

Я считал, что они синонимы; все же, если я изменю

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

to

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

Я получаю ошибку компилятора (gcc 4.1.2)

запрошено преобразование из ‘__gnu_cxx::__normal_iterator, std::allocator > >’ в нескалярный тип ‘Glib::ustring_Iterator‹__gnu_cxx::__normal_iterator, std::allocator > > >’

большое спасибо!


person davka    schedule 30.05.2010    source источник
comment
Я получаю ошибку компилятора... что иногда... Если вы опубликуете точный код и точное сообщение об ошибке, которое он вызывает, людям будет намного проще помочь.   -  person James McNellis    schedule 30.05.2010
comment
в том то и дело - я получаю разные сообщения об ошибках при разных компиляциях, что само по себе довольно странно   -  person davka    schedule 30.05.2010


Ответы (1)


Ваше объявление объявляет эту функцию:

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

Скобки в вашем коде вокруг s игнорируются. Они похожи на круглые скобки вокруг n в следующем примере.

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

Они предназначены для группировки модификаторов, таких как указатель (*) или ссылки (&) (подумайте о void(*fptr)()). В вашем случае скобки просто семантически избыточны.

Вместо этого попробуйте это:

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

Введенные круглые скобки заставляют компилятор признать, что вместо этого он должен создавать объект, p инициализированный из выражения (поскольку объявление параметра функции не может иметь круглых скобок, оно анализируется не как объявление параметра, а как инициализатор).

person Johannes Schaub - litb    schedule 30.05.2010
comment
Большое спасибо! почему версия Glib::ustring::iterator p = string::iterator(s); хоть работать? Кажется, что в нем нет этой двусмысленности. - person davka; 30.05.2010
comment
@davka при инициализации допускается только одно определяемое пользователем преобразование, и в этой форме используются только неявные конструкторы копирования. Любой из этих двух фактов может вызвать ошибку компиляции. - person Johannes Schaub - litb; 30.05.2010