Re[5]: Можно использовать вектор как массив для возврата зна
От: Кодт Россия  
Дата: 03.06.10 22:55
Оценка: 8 (1)
Здравствуйте, Marty, Вы писали:

M>::std::vector< colorref_vector, IPoolAllocator<colorref_vector> >
M>   faceColors( IPoolAllocator<colorref_vector>(poolPtr) );
//   ~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~
//   имя функции      тип аргумента              имя аргумента


К>>Трюк с лишними скобками знаешь?

::std::vector< colorref_vector, IPoolAllocator<colorref_vector> >
   faceColors( ( IPoolAllocator<colorref_vector>(poolPtr) ) );
//             ~                                          ~


Дистиллированный пример
http://codepad.org/LsRB3kwk
Перекуём баги на фичи!
Re[3]: Можно использовать вектор как массив для возврата зна
От: IROV..  
Дата: 02.06.10 17:39
Оценка: 1 (1)
Здравствуйте, dilmah, Вы писали:

LVV>>Можно. Но я б рекомендовал параметрами SomeFunc сделать в стиле stl

M>>>
M>>>void SomeFunc( int *begin, int *end)
M>>>


D>не вижу никакого бенефита в такой форме. Бенефит был бы, если бы функция стала шаблонной, а если жестко прописаны int*, то какая разница begin+size или begin+end?


Уточню, бенифит от begin + end мы достигаем когда используем итераторы таких контейнеров как list.
тоесть там где мы не можем себе позволить хранить сайз

я не волшебник, я только учусь!
Re: Можно использовать вектор как массив для возврата значен
От: LaptevVV Россия  
Дата: 02.06.10 15:26
Оценка: -1
Здравствуйте, Marty, Вы писали:
M> Допустим, есть:
M>
M>void SomeFunc( int *pData, size_t dataSize)
M>

M>Можно ли использовать для этого вектор:
Можно. Но я б рекомендовал параметрами SomeFunc сделать в стиле stl
M>
M>void SomeFunc( int *begin, int *end)
M>
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Можно использовать вектор как массив для возврата зна
От: dilmah США  
Дата: 02.06.10 16:15
Оценка: +1
LVV>Можно. Но я б рекомендовал параметрами SomeFunc сделать в стиле stl
M>>
M>>void SomeFunc( int *begin, int *end)
M>>


не вижу никакого бенефита в такой форме. Бенефит был бы, если бы функция стала шаблонной, а если жестко прописаны int*, то какая разница begin+size или begin+end?
Можно использовать вектор как массив для возврата значений?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.06.10 13:36
Оценка:
Здравствуйте, коллеги!

Допустим, есть:
void SomeFunc( int *pData, size_t dataSize)
 {
  // возвращаем что-то.
  for(; dataSize; --dataSize, ++pData)
     *pData = (int)dataSize;
 }


Можно ли использовать для этого вектор:
std::vector<int> vec;
vec.assign( 32, 0 ); // подготовили место
SomeFunc( &(*vec.begin()), vec.size() ); // хотим получить новые значения


На мой взгляд, криминала нет, но вдруг я ошибаюсь?

03.06.10 13:46: Перенесено из 'C/C++. Прикладные вопросы'
Маньяк Робокряк колесит по городу
Re: Можно использовать вектор как массив для возврата значен
От: March_rabbit  
Дата: 02.06.10 13:40
Оценка:
Здравствуйте, Marty, Вы писали:

M> Здравствуйте, коллеги!


M> Допустим, есть:

M>
M>void SomeFunc( int *pData, size_t dataSize)
M> {
M>  // возвращаем что-то.
M>  for(; dataSize; --dataSize, ++pData)
M>     *pData = (int)dataSize;
M> }
M>


M>Можно ли использовать для этого вектор:

M>
M>std::vector<int> vec;
M>vec.assign( 32, 0 ); // подготовили место
M>SomeFunc( &(*vec.begin()), vec.size() ); // хотим получить новые значения 
M>


M>На мой взгляд, криминала нет, но вдруг я ошибаюсь?

ИМХА говорит, что все нормально, хоть и выглядит не красиво.
Re: Можно использовать вектор как массив для возврата значен
От: dilmah США  
Дата: 02.06.10 14:03
Оценка:
M>На мой взгляд, криминала нет, но вдруг я ошибаюсь?

это была после 98-го года спецпоправка в стандарт на эту тему, что элементы вектора лежат непрерывно в памяти, то есть это легально.
Re[2]: Можно использовать вектор как массив для возврата зна
От: Слава Израиль  
Дата: 02.06.10 14:38
Оценка:
Здравствуйте, March_rabbit, Вы писали:

M>>Можно ли использовать для этого вектор:

M>>
M>>std::vector<int> vec;
M>>vec.assign( 32, 0 ); // подготовили место
M>>SomeFunc( &(*vec.begin()), vec.size() ); // хотим получить новые значения 
M>>


M>>На мой взгляд, криминала нет, но вдруг я ошибаюсь?

M_>ИМХА говорит, что все нормально, хоть и выглядит не красиво.

А так красивее?

SomeFunc( &vec[0], vec.size() );
Спасибо за внимание
Re: Можно использовать вектор как массив для возврата значен
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.06.10 14:57
Оценка:
Здравствуйте, Marty, Вы писали:

Спасибо всем ответившим.
Маньяк Робокряк колесит по городу
Re[2]: Можно использовать вектор как массив для возврата зна
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.06.10 15:33
Оценка:
Здравствуйте, LaptevVV, Вы писали:

Мысль интересная, надо подумать.
Маньяк Робокряк колесит по городу
Re[2]: Можно использовать вектор как массив для возврата зна
От: Acteon  
Дата: 02.06.10 16:00
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, Marty, Вы писали:

M>> Допустим, есть:
M>>
M>>void SomeFunc( int *pData, size_t dataSize)
M>>

M>>Можно ли использовать для этого вектор:
LVV>Можно. Но я б рекомендовал параметрами SomeFunc сделать в стиле stl
M>>
M>>void SomeFunc( int *begin, int *end)
M>>


Это только если SomeFunc твоя функция. У меня в одном приложении было нечто похожее. Внутри гнал массивы через векторы (особенно полезно когда надо передавать два массива или три, экономим параметры под размеры массивов). А с WinAPI стыковался через &vec.front(), vec.size().
Re[3]: Можно использовать вектор как массив для возврата зна
От: gear nuke  
Дата: 02.06.10 17:06
Оценка:
Здравствуйте, Marty,

Если SomeFunc можно менять, более безопасен подобный вариант:

template <typename Iter>
void SomeFunc(Iter pData, size_t dataSize)
 {
  for(; dataSize; --dataSize, ++pData)
     *pData = (int)dataSize;
 }
 
    
  std::vector<int> vec;
  SomeFunc(std::back_inserter(vec), 5);
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Можно использовать вектор как массив для возврата значен
От: Кодт Россия  
Дата: 03.06.10 09:52
Оценка:
Здравствуйте, Marty, Вы писали:

Единственный криминал — это отсутствие проверки на 0.

Если dataSize=0, то vector<int>(dataSize) пуст.
Его begin()==end(), а end() разыменовывать нельзя. Даже для последующего взятия адреса.
Равно как нельзя обращаться к [0] и front().
Это undefined behavior.
(Во-первых, вектор может сконструироваться с NULL-указателями, а во-вторых, там — в дебажной версии точно — могут стоять проверки на вылет из диапазона).

Поэтому, нужно либо гарантированно резервировать, vector<int>(max(1,dataSize))
либо ветвить: SomeFunc(dataSize ? &v.front() : NULL_OR_ZERO_LENGTH_ARRAY, dataSize)

Кстати, обращаю внимание: вместо assign можно сразу в конструктор вектора передавать размер.
Перекуём баги на фичи!
Re[2]: Можно использовать вектор как массив для возврата зна
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.10 10:22
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Marty, Вы писали:


К>Единственный криминал — это отсутствие проверки на 0.


Ну, подразумевается, что 0 никогда не будет.
Смысл затеи — возвращать вектора простых (хотя бы) типов через сишный интерфейс.
Идея в том, что первый вызов (вместо указателя передаем 0) дает размер массива, который будет возвращен, затем подготавливается вектор под это дело и
передаем указатель на первый элемент. Как возвращать размер на первом шаге — наверно надо сделать dataSize указателем на size_t, и принимать размер в него. Хотя, тогда на втором шаге не так удобно.

Спасибо за подсказку.

К>Кстати, обращаю внимание: вместо assign можно сразу в конструктор вектора передавать размер.


Да я просто мучался перед написанием поста с тем, что инициализация конструктором с параметрами не компилировалась (в gcc вроде), выдавалось что-то невнятное, как я понял, компилятор воспринял это как объявление функции
Маньяк Робокряк колесит по городу
Re[3]: Можно использовать вектор как массив для возврата зна
От: Кодт Россия  
Дата: 03.06.10 12:01
Оценка:
Здравствуйте, Marty, Вы писали:

M>Да я просто мучался перед написанием поста с тем, что инициализация конструктором с параметрами не компилировалась (в gcc вроде), выдавалось что-то невнятное, как я понял, компилятор воспринял это как объявление функции


Пример кода?
Трюк с лишними скобками знаешь?
Перекуём баги на фичи!
Re: Можно использовать вектор как массив для возврата значен
От: B7_Ruslan  
Дата: 03.06.10 12:12
Оценка:
А почему бы просто вектор по ссылке не передать?
А если функцию изменить нельзя, то наверно лучше
SomeFunc( &(vec.front()), vec.size() );
Re[3]: Можно использовать вектор как массив для возврата зна
От: March_rabbit  
Дата: 03.06.10 12:30
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте, March_rabbit, Вы писали:


M>>>Можно ли использовать для этого вектор:

M>>>
M>>>std::vector<int> vec;
M>>>vec.assign( 32, 0 ); // подготовили место
M>>>SomeFunc( &(*vec.begin()), vec.size() ); // хотим получить новые значения 
M>>>


M>>>На мой взгляд, криминала нет, но вдруг я ошибаюсь?

M_>>ИМХА говорит, что все нормально, хоть и выглядит не красиво.

С>А так красивее?


С>SomeFunc( &vec[0], vec.size() );

это вопрос эстетики второй вариант покрасивше, символов поменьше.
но (как уже и говорил) — все нормально.
Re[3]: Можно использовать вектор как массив для возврата зна
От: Centaur Россия  
Дата: 03.06.10 17:26
Оценка:
Здравствуйте, Marty, Вы писали:

К>>Единственный криминал — это отсутствие проверки на 0.


M>Ну, подразумевается, что 0 никогда не будет.

M>Смысл затеи — возвращать вектора простых (хотя бы) типов через сишный интерфейс.
M>Идея в том, что первый вызов (вместо указателя передаем 0) дает размер массива, который будет возвращен, затем подготавливается вектор под это дело и передаем указатель на первый элемент.

Ну и в частном случае первый вызов скажет, что размер данных — 0. Подготавливаем вектор, пытаемся передать указатель на первый элемент — и вываливаемся в проверке (index < size) в vector::operator[].
Re[2]: Можно использовать вектор как массив для возврата зна
От: s.ts  
Дата: 03.06.10 19:10
Оценка:
Здравствуйте, LaptevVV, Вы писали:

Вредные советы.
Коль уж есть api в стиле "c", то и нужно их таковми делать.
Т.е. мой выбор — или 2 итератора на входе, или как есть.

LVV>Здравствуйте, Marty, Вы писали:

M>> Допустим, есть:
M>>
M>>void SomeFunc( int *pData, size_t dataSize)
M>>

M>>Можно ли использовать для этого вектор:
LVV>Можно. Но я б рекомендовал параметрами SomeFunc сделать в стиле stl
M>>
M>>void SomeFunc( int *begin, int *end)
M>>
Re[4]: Можно использовать вектор как массив для возврата зна
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.10 21:26
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Пример кода?


Точно уже не скажу, я забил и переделал так, что вся эта фигня не понадобилась. Последний вариант такой, он тоже что не заработал, хотя может уже где-то в другом месте, предыдущий по памяти восстановил ниже:
        typedef vector< COLORREF, IPoolAllocator<COLORREF> > colorref_vector;
        ::std::vector< colorref_vector, IPoolAllocator<colorref_vector> > faceColors      = ::std::vector< colorref_vector, IPoolAllocator<colorref_vector> >( IPoolAllocator<colorref_vector>(poolPtr) );
        ::std::vector< colorref_vector, IPoolAllocator<colorref_vector> > faceColors( IPoolAllocator<colorref_vector>(poolPtr) ); // не работал вот этот, похоже по сообщениям воспринимался как прототип.


К>Трюк с лишними скобками знаешь?

Примерно так:
CMyType var()( /* bla-bla */);

Что-то вроде этого? Это вроде похоже на вызов оператора (). Нет, не знаю
Маньяк Робокряк колесит по городу
Re[4]: Можно использовать вектор как массив для возврата зна
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.10 21:28
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Ну и в частном случае первый вызов скажет, что размер данных — 0. Подготавливаем вектор, пытаемся передать указатель на первый элемент — и вываливаемся в проверке (index < size) в vector::operator[].

Ну, если кол-во возвращаемых данных — 0, то наверно можно и вообще не вызывать Хотя это от функции зависит, конечно.
Маньяк Робокряк колесит по городу
Re[3]: Можно использовать вектор как массив для возврата зна
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.10 21:31
Оценка:
Здравствуйте, dilmah, Вы писали:

D>не вижу никакого бенефита в такой форме. Бенефит был бы, если бы функция стала шаблонной, а если жестко прописаны int*, то какая разница begin+size или begin+end?


Ну, бенефиты в том, что если SomeFunc тоже наша функция, то для возврата значения можно использовать std алгоритмы. Хотя из begin+size тоже самое можно получить
Маньяк Робокряк колесит по городу
Re[2]: Можно использовать вектор как массив для возврата зна
От: GhostCoders Россия  
Дата: 04.06.10 08:08
Оценка:
Здравствуйте, B7_Ruslan, Вы писали:

B_R>А почему бы просто вектор по ссылке не передать?

B_R>А если функцию изменить нельзя, то наверно лучше
B_R>
B_R>SomeFunc( &(vec.front()), vec.size() );
B_R>


Мне кажется это не совсем есть гуд. Если этот метод будет в другой библиотеке (статической или же динамической, без разницы),
то возможна мешанина с разными кучами (например, std::vector<> был инициализирован в одной куче 10 элементами, а другой он будет расширен до 20) —
как результат падание на следующей функции работащией с кучей (с выдачей сообщения что C Runtime heap поврежден).
Третий Рим должен пасть!
Re[3]: Можно использовать вектор как массив для возврата зна
От: B7_Ruslan  
Дата: 07.06.10 10:53
Оценка:
Здравствуйте, GhostCoders, Вы писали:

GC>Мне кажется это не совсем есть гуд. Если этот метод будет в другой библиотеке (статической или же динамической, без разницы),

GC>то возможна мешанина с разными кучами (например, std::vector<> был инициализирован в одной куче 10 элементами, а другой он будет расширен до 20) —
GC>как результат падание на следующей функции работащией с кучей (с выдачей сообщения что C Runtime heap поврежден).

А какую литературу можно почитать на эту тему?
Re[4]: Можно использовать вектор как массив для возврата зна
От: GhostCoders Россия  
Дата: 07.06.10 15:16
Оценка:
Здравствуйте, B7_Ruslan, Вы писали:

GC>>Мне кажется это не совсем есть гуд. Если этот метод будет в другой библиотеке (статической или же динамической, без разницы),

GC>>то возможна мешанина с разными кучами (например, std::vector<> был инициализирован в одной куче 10 элементами, а другой он будет расширен до 20) —
GC>>как результат падание на следующей функции работащией с кучей (с выдачей сообщения что C Runtime heap поврежден).

B_R>А какую литературу можно почитать на эту тему?

Какую литературу не знаю, так как проверенно на собственном опыте. Но думаю что-нибудь про архитектуру процессов, потоков, более
общее, так как "Программирование для Windows" Рихтера, "Inside COM" (автора не помню, хоть COM тут напрямую не завязан, но книжка хорошая,
позволяет заглянуть как работает Windows).

Сам бы хотел просмотреть подобную литературу.
Третий Рим должен пасть!
Re[6]: Можно использовать вектор как массив для возврата зна
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 08.06.10 19:40
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Дистиллированный пример

К>http://codepad.org/LsRB3kwk

Спасибо/ Знал, но забыл
Маньяк Робокряк колесит по городу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.