Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> неявное преобразование итератора в указатель 
:(
    Опции темы
neosapient
Дата 22.12.2009, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Здравствуйте.

В VC6 использовал следующий прием для копирования элементов в контейнере: переопределял операцию присваивания значения по указателю.
Далее в коде пробую присвоить значение элементу через итератор указывающий на другой элемент в vectore.
VC6 спокойно воспринимает преобразование из итератора в указатель. VC9 ругается на подобное преобразование. 
Цитата

c:\documents and settings\user\desktop\ublas\testiterator\main.cpp(50) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Vector_iterator<_Ty,_Alloc>' (or there is no acceptable conversion)
with
[
    _Ty=MyStruct,
    _Alloc=std::allocator<MyStruct>
]
c:\documents and settings\zhukov\desktop\ublas\testiterator\main.cpp(13): could be 'MyStruct &MyStruct::operator =(const MyStruct &)'
c:\documents and settings\zhukov\desktop\ublas\testiterator\main.cpp(18): or       'MyStruct &MyStruct::operator =(const MyStruct *)'
while trying to match the argument list '(MyStruct, std::_Vector_iterator<_Ty,_Alloc>)'
with
[
     _Ty=MyStruct,
    _Alloc=std::allocator<MyStruct>
]


Подскажите, как правильно переписать пример для VC9 ?

Вот код примера
Код

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

#include <vector>
#include <list>
using namespace std;


class MyStruct
{
public:
    MyStruct &operator=(const MyStruct &other)
    {
        memcpy(this, &other, sizeof(MyStruct));
        return *this;
    }
    MyStruct &operator=(const MyStruct *other)
    {
        if(other==NULL){
            memset(this, 0, sizeof(MyStruct));
            return *this;
        }
        else{
            memcpy(this, other, sizeof(MyStruct));
            return *this;
        }
    }
public:
    int alfa;
    double betta;
};

int main(int argc,char * argv[])
{
    int i;
    MyStruct  mass[3] = {{1,1.0},{2,2.0},{3,3.0}};
    vector<MyStruct> Vect;
    list<MyStruct> List;
    vector<MyStruct>::iterator Iter;
    MyStruct item;
    // заполняем вектор
    Vect.clear();
    for(i=0; i<3; i++){
        Vect.push_back(mass[i]);
    }
    // заполняем список
    List.clear();
    for(Iter = Vect.begin(); Iter != Vect.end(); ++Iter){
        item = Iter;  // <-- в этом месте в VC9 итератор перестает восприниматься как указатель
        List.push_back(item);
    }
    //----
    return 0;
}


Это сообщение отредактировал(а) neosapient - 22.12.2009, 13:12
PM MAIL   Вверх
bsa
Дата 22.12.2009, 12:16 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



neosapient, MyStruct &operator=(const MyStruct *other) - вообще выкини.
Код
item = Iter;  // <-- в этом месте в VC9 итератор перестает восприниматься как указатель
замени на
Код
item = *Iter;

PM   Вверх
neosapient
Дата 22.12.2009, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Ещё один вопрос, по обратной задаче
Преобразую итератор к NULL-евому указателю. Но компилятор ругается. Как это можно исправить.
Цитата

1>c:\documents and settings\user\desktop\testiterator\main.cpp(43) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector(405): could be 'std::_Vector_iterator<_Ty,_Alloc> &std::_Vector_iterator<_Ty,_Alloc>::operator =(const std::_Vector_iterator<_Ty,_Alloc> &)'
1>        with
1>        [
1>            _Ty=MyStruct,
1>            _Alloc=std::allocator<MyStruct>
1>        ]
1>        while trying to match the argument list '(std::_Vector_iterator<_Ty,_Alloc>, int)'
1>        with
1>        [
1>            _Ty=MyStruct,
1>            _Alloc=std::allocator<MyStruct>
1>        ]


Код

int main(int argc,char * argv[])
{...
    Iter=NULL;
}

PM MAIL   Вверх
bsa
Дата 22.12.2009, 21:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



neosapient, ты видимо вообще не понимаешь, что такое итератор. Итератор - это объект, который ведет себя как указатель. В частности, есть итераторы ввода (std::istream_iterator) и вывода (std::ostream_iterator)... Как ты их преобразуешь в указатели?

Итератор, обычно, это способ доступа к данным контейнера. Соответственно, контейнер всегда имеет методы, которые позволяют узнать начальный итератор и конечный (который ни на что не ссылается - аналог NULL). Эти методы у стандартных контейнеров называются begin() и end() (или rbegin() и rend(), если нужна обратная последовательность перебора). Таким образом, когда итератор после ряда операций приращения стал равен end(), то достигнут конец данных.

В твоем случае есть смысл заменить на Iter = Vect.end(), только имей в виду, что Vect.end() != NULL и операция if (Iter) {}, если скомпилируется, то будет всегда true.
PM   Вверх
Earnest
Дата 23.12.2009, 07:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



neosapient, в старой среде VC^6 действительно использовалась версия STL, где итераторы, по крайней мере, вектора и были реализованы как указатели. Но уже с 7й версии это не так. Итератор - не указатель! Но преобразовать итератор к указателю на элемент легко:
 CItem* pItem = &(*iter), где iter - это итератор контейнера, в котором лежат CItem. Т.е. сначала разыменовываем и получаем ссылку на элемент, а потом берем адрес.
Вот наоборот сделать нельзя (в общем случае) - т.е. из указателя в итератор. Т.е. для вектора-то можно всегда, пользуясь тем, что память обязательно непрерывна, а вот для других контейнеров - очень сильно зависит от реализации STL, и не все это позволяют. 
Грубо говоря, нужно смотреть, есть ли у итератора открытый конструктор от ссылки или указателя на значение.
Так что не стоит так делать.


--------------------
...
PM   Вверх
maxim1000
Дата 23.12.2009, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(Earnest @  23.12.2009,  07:29 Найти цитируемый пост)
Но преобразовать итератор к указателю на элемент легко:
 CItem* pItem = &(*iter), где iter - это итератор контейнера, в котором лежат CItem. Т.е. сначала разыменовываем и получаем ссылку на элемент, а потом берем адрес.

маленькая добавочка:
TContainer::end() вернёт вполне корректный объект-итератор, который не стоит разыменовывать, да и указатель ему никакой не соответствует

конечно, для разыменовываемых итераторов такой способ работает


--------------------
qqq
PM WWW   Вверх
Adjusly
Дата 24.1.2023, 01:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 23.1.2023

Репутация: нет
Всего: нет




Модератор: Сообщение скрыто.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1321 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.