Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [MSVC 2008] преобразовать указатель к итератору 
V
    Опции темы
borisbn
Дата 5.3.2011, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Добрый день!
В 2008-й студии на такой код
Код

typedef std::vector< int > IVector;
const int * p;
IVector::const_iterator it( p );

выдаёт ошибку
Цитата

error C2664: 'std::_Vector_const_iterator<_Ty,_Alloc>::_Vector_const_iterator(const std::_Vector_const_iterator<_Ty,_Alloc> &)' : cannot convert parameter 1 from 'const int *' to 'const std::_Vector_const_iterator<_Ty,_Alloc> &' 

погуглил, поMSDNил нашёл 2 дефайна, которые, как мне казалось, отвечают за это.
добавил в проект два дефайна
Цитата

_SCL_SECURE_NO_WARNINGS
и
_HAS_ITERATOR_DEBUGGING 0

результат тот же.
Подскажите, пожалуйста, как в студии преобразовать указатель к итератору.
Спасибо.

P.S. без const тоже пробовал. результат тот же

Это сообщение отредактировал(а) borisbn - 6.3.2011, 11:28


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
maxim1000
Дата 5.3.2011, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



хм... а с чего бы это им кастоваться друг к другу
итератор является указателем разве что семантически, да и то уже перерос это понятие
в терминах языка итератор и указатель - две разные вещи

используя специфику std::vector (то, что он обязан хранить объекты друг за другом) можно сделать так:
Код

std::vector<int>::iterator i=someVector.begin()+(p-&someVector.front());


Добавлено через 2 минуты и 11 секунд
P.S.
есть сильное ощущение, что стоит обратить внимание на ту функциональность, которая генерирует эти указатели - может она должна выдавать итераторы?


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


hell is here
**


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

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



ни разу не обязано работать такое преобразование
iterator сам себе объект, кастование к нему не имеет здравого смысла, ибо итератор должен скрывать в себе реализацию контейнера и самого обхода, а не открывать к ним лазейки

и в чем смысл использования?
PM MAIL   Вверх
borisbn
Дата 6.3.2011, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



сорри, что не отвечал вовремя - женщин поздравляли smile
Цитата(maxim1000 @  5.3.2011,  14:51 Найти цитируемый пост)
а с чего бы это им кастоваться друг к другу

а почему бы и нет ?
Код

std::что_нибудь_требующее_итератор( pointer_to_int, pointer_to_int + length )

так что-ли тоже нельзя ?

Цитата(maxim1000 @  5.3.2011,  14:51 Найти цитируемый пост)
есть сильное ощущение, что стоит обратить внимание на ту функциональность, которая генерирует эти указатели - может она должна выдавать итераторы?

на 250% согласен, но код не мой, там такого немало, и на дебилдере он компилируется, а на студии - нет (кстати, на liveworkspace пробовал - работает, а там, кажется gcc)
на самом деле я упростил код до минимума. в оригинале было так
Код

bool findSequence( const unsigned char * buf, unsigned int buf_len, const UCVector & seq, unsigned int & pos ) {
    UCVector::const_iterator it = std::search( buf, // вот тут и ругался
       buf + buf_len, // здесь ессно тоже
       seq.begin(), seq.end() );
...
}




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Albor
Дата 6.3.2011, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



borisbn, возвращаемое значение алгоритма search  должно быть такого же типа как и тип итераторов диапазона для поиска, то есть const unsigned char *, почему в коде значение принимает другой тип не понятно - не выполняются требования к типам для данного алгоритма.
PM MAIL ICQ   Вверх
maxim1000
Дата 6.3.2011, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(borisbn @  6.3.2011,  12:19 Найти цитируемый пост)
а почему бы и нет ?
Код

std::что_нибудь_требующее_итератор( pointer_to_int, pointer_to_int + length )

так что-ли тоже нельзя ?

в такую сторону можно, т.к. итератор в C++ обобщает понятие указателя

более того, указатель - наиболее естественный итератор для "куска памяти", так что если передаётся unsigned char *buf, то и итератор в этом "куске памяти" должен быть указателем, как предложил Albor

а то ведь к коде функции вообще нет никаких оснований ожидать, что buf указывает на какой-либо контейнер, так что и приводить указатель на его элемент к итератору, специфическому для какого-то контейнера, неправильно...

Добавлено @ 20:28
кстати, а как потом используется it?
а то создаётся впечатление, что произошла обычная человеческая ошибка во время разработки этого кода, которую компилятор не отловил, - вместо типа первой пары итераторов для результата был выбран тип второй

Это сообщение отредактировал(а) maxim1000 - 6.3.2011, 20:28


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(maxim1000 @  6.3.2011,  20:23 Найти цитируемый пост)
а то ведь к коде функции вообще нет никаких оснований ожидать, что buf указывает на какой-либо контейнер, так что и приводить указатель на его элемент к итератору, специфическому для какого-то контейнера, неправильно...

неправильно то неправильно... чисто по человеческой логике, но мне непонятно, почему это не работает по "компиляторной" логике ? Почему не вызывается конструктор итератора типа iterator( T* ) ? Я посмотрел в коде студийного STL - там есть такой конструктор, он explicit, но, даже если я сделаю явное преобразование (как в самом первом посте), всё равно ошибка.

И, кстати, там этот конструктор "открывается", т.е. вообще присутствует в классе, по куче define'ов, так, что я так понимаю мне чтобы добиться компиляции этого кода, нужно просто прописать какой-то define в студии...

И ещё. Я не случайно выбрал именно этот раздел форума, т.к. этот код, повторюсь, работает и в билдере и в gcc.

То, что код не совсем корректный - ну может быть... убедили smile Но оооочень не хочется его переделывать, т.к. там такого много.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Earnest
Дата 9.3.2011, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



explicit относится к конструктору, а не к преобразованию; это разные вещи вообще-то. Просто привыкаешь, что оно все работает само собой без дополнительных букв. Как раз поэтому и ругается, насколько я понимаю, что даже явное преобразование требует конструктора, который explicit, т.е. имеет право вызываться только лично программером. Используй форму конструктора, а не преобразования, тогда должно пройти. Я сталкивалась с тем, что в 2008 это дело строже, чем раньше было... Что, в общем, неплохо, ибо явное указание на грязь в коде...но при переходе между компиляторами, конечно, раздражает (типа все там работало, а здесь...). Что в билдере компилируется, не аргумент, реализация библиотеки другая. В 2003 тоже должно скомпилироваться. Лучше этого избегать. Тебе ведь правильно разъяснили, что указатель есть итератор, но обратное неверно.
С переделками действительно нужно поаккуратнее - практика показывает, что даже самые казалось бы безобидные изменения кода могут приводить к ошибкам, т.е. все требует тщательного тестирования... Попробуй обойтись малой кровью (используй для приведения форму конструктора), если уверен в сути.


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(Earnest @  9.3.2011,  12:30 Найти цитируемый пост)
Используй форму конструктора, а не преобразования, тогда должно пройти

дык, пробовал (см. самое первое сообщения этой темы)...
Цитата(Earnest @  9.3.2011,  12:30 Найти цитируемый пост)
Лучше этого избегать.

повторю, код не мой и его (кода) много. А если это на будущее - то спасибо, буду избегать.
Цитата(Earnest @  9.3.2011,  12:30 Найти цитируемый пост)
Что в билдере компилируется, не аргумент

ессно, не аргумент, но ведь и в gcc компилируется...
и ещё вот здесь (пример в конце)

В общем, у меня вопрос не по корректности этого кода, а как заставить студию его откомпилировать (какой дефайн где прописать) ? Ответ - никак - тоже принимается, но с пруф-линком smile Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Earnest
Дата 10.3.2011, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(borisbn @  9.3.2011,  14:51 Найти цитируемый пост)
дык, пробовал (см. самое первое сообщения этой темы)...

Пардон, пропустила...
Странно, точно помню, что у меня была такая же проблема при переходе с 2003 на 2008, использовались неявное преобразование, помог конструктор... правда вроде не const там было. 
Посмотрела еще раз проблемный код, который не компилируется:
Код

bool findSequence( const unsigned char * buf, unsigned int buf_len, const UCVector & seq, unsigned int & pos ) {
    UCVector::const_iterator it = std::search( buf, // вот тут и ругался
       buf + buf_len, // здесь ессно тоже
       seq.begin(), seq.end() );

Здесь результат ведь должен иметь тип первого итератора, т.е. константный указатель внутрь буфера (const unsigned char * buf). Раньше компилировалось, т.к. неявно преобразовывалось в UCVector::const_iterator. Но вообще-то это некорректно.

Добавлено через 2 минуты и 7 секунд
Вижу, об этом уже говорил Albor


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(Earnest @  10.3.2011,  09:47 Найти цитируемый пост)
Но вообще-то это некорректно.


Цитата(borisbn @  9.3.2011,  13:51 Найти цитируемый пост)
В общем, у меня вопрос не по корректности этого кода, а как заставить студию его откомпилировать (какой дефайн где прописать) ? Ответ - никак - тоже принимается, но с пруф-линком  Спасибо.

 smile 


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Earnest
Дата 10.3.2011, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Те дефайны, которые ты привел, действительно позволяют конструировать итератор вектора из указателя, но не const указателя (точнее, не указателя на константу). Потому и не компилируется, несмотря на наличие явного конструктора. Там ведь так:
Код

typedef typename _Alloc::pointer _Tptr;
explicit _Vector_const_iterator(_Tptr _Ptr)

Кроме того, из приведенного кода непонятно, что такое UCVector. Если там хранятся unsigned char как в буфере, то скорее всего поможет отбитие const



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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(Earnest @  10.3.2011,  13:05 Найти цитируемый пост)
то скорее всего поможет отбитие const

нет. 
Цитата(borisbn @  5.3.2011,  12:33 Найти цитируемый пост)
P.S. без const тоже пробовал. результат тот же

Код

typedef std::vector< int > IVector;
    int * p;
    IVector v;
    int * pp = std::search( p, p + 1, v.begin(), v.end() );
    IVector::iterator it( pp ); // Ошибка


Добавлено через 7 минут и 25 секунд
Ладно, забейте. Я уже вышел из ситуации ( м.б. не лучшим способом, но никто ж, пока, не подсказал лучший smile )
Я собрал на билдере из этого кода dll-ку, которую подключил к проекту на студии. Всё работает как надо.
Тему закрываю, но если возникнут идеи - you're wellcome smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 11.3.2011, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

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



Цитата(borisbn @  10.3.2011,  11:21 Найти цитируемый пост)
как заставить студию его откомпилировать (какой дефайн где прописать) ? 

Сегодня решил немного покопаться в исходниках студийной стл.
В общем решение лежало близко...

Код

#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0
#include <vector>
#include <algorithm>

void aaa(int * p)
{
    typedef std::vector< int > IVector;
    IVector v;
    int * pp = std::search( p, p + 1, v.begin(), v.end() );
    IVector::iterator it(pp);        // Не константный работает
    IVector::const_iterator itc(pp); // И константный тоже!
}


Код

1>Compiling...
1>vingrad.cpp
1>Linking...
1>vingrad - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

MSVS 2008 И в дебаге, и в релизе.
smile

PM MAIL   Вверх
borisbn
Дата 11.3.2011, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



volatile, спасибо огромное !!!
А ведь искал же... и даже видел эти дефайны... просто не дошло, что их нужно оба установить в 0.

P.S. К сожалению мой реальный (не тестовый) код всё равно без переделок не откомпиляешь, т.к. конструктор итератора explicit, а у меня
Код

UCVector::const_iterator it = std::search( buf, buf + buf_len, seq.begin(), seq.end() );


Но всё равно спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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