Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Копирование из std::vector::iterator в параметриз.


Автор: EvilsInterrupt 18.8.2010, 09:28
Пишу шаблонный класс:

Код

template<typename T>
class CBuffer {
  typedef   std::vector<T>              VecT_t;
  typedef   typename VecT_t::iterator   VecTItr_t;
public:
  CBuffer(int len) : m_Content.reserve(len)           {}
  CBuffer(T * buf, int len) : m_Content(buf, buf+len) {}

  int tail()    { return((int)m_Content.capacity()-length()); }
  int length()  { return((int)m_Content.size() );             }

  int get(T * data, int offs, int len) {
    int res = len && IsValid(offs) ? length()-offs : 0;
    if(res>0) {
      res = std::min(res, len);

      VecTItr_t beg = m_Content.begin() + offs;
      VecTItr_t end = beg + res;
      std::copy(beg, end, data);
    }
    return(res>0 ? res : 0);
  }

  int put(T * data, int offs, int len) {
    int res = len && IsValid(offs) ? tail() - offs : 0;
    if(res > 0) {
// TODO:
    }
    return(res);
  }

private:

  VecT_t    m_Content;
  int       m_Index;

  bool      IsValid(int offs) { 
    return(offs>=0 && offs < (int)m_Content.capacity()); 
  }
};


Главный вопрос:
пытаюсь в get скопировать из вектора в T * алгоритмом std::copy , но  не получается. ругается такой ошибкой:
Цитата

1>e:\source\proba\buffer.hpp(26) : warning C4996: 'std::copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(2550) : see declaration of 'std::copy'
1>        e:\source\proba\buffer.hpp(19) : while compiling class template member function 'int CBuffer<T>::get(T *,int,int)'
1>        with
1>        [
1>            T=UChar
1>        ]
1>        e:\source\proba\proba.cpp(15) : see reference to class template instantiation 'CBuffer<T>' being compiled
1>        with
1>        [
1>            T=UChar
1>        ]


вопрос, как это сделать ?

Второстепенный:
  typedef   typename VecT_t::iterator   VecTItr_t;
Почему в этом месте компиллер нуждается в написании ключевого слова "typename" ?

Автор: azesmcar 18.8.2010, 09:37
Цитата(EvilsInterrupt @  18.8.2010,  09:28 Найти цитируемый пост)
но  не получается. ругается такой ошибкой

Это не ошибка, это предупреждение, 

Автор: EgorTheBlade 18.8.2010, 09:38
Подключите в свойствах проекта 
-D_SCL_SECURE_NO_WARNINGS;

Автор: EvilsInterrupt 18.8.2010, 09:41
>>-D_SCL_SECURE_NO_WARNINGS;
но тогда я лишусь проверки других функций, а не вот этого  конкретного места. Как сказать компиллеру (MSVC 2008/2010) что именно в этом месте, а я отлично  шарю чего  делаю и все вычислил для этого ?

Добавлено через 1 минуту и 19 секунд
>>Это не ошибка, это предупреждение, 
был бы варнинг, то позволил бы выполнять код и до работал бы до поставленного мною бряка!

а у меня на последней стоит бряк:
Код

  UChar a[5] = {0x20, 0x31, 0x10, 0x49, 0x9A};

  CBuffer<UChar> RdrBuf(a, 5);

  UChar b[10] = {0};

  int c = RdrBuf.get(b,0,3);
  M_MSG(c);


и не срабатывает!

Автор: azesmcar 18.8.2010, 09:46
Цитата(EvilsInterrupt @  18.8.2010,  09:41 Найти цитируемый пост)
был бы варнинг, то позволил бы выполнять код и до работал бы до поставленного мною бряка!

т.е. слово 
Цитата(EvilsInterrupt @  18.8.2010,  09:28 Найти цитируемый пост)
warning 

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

Добавлено через 2 минуты и 8 секунд
Цитата(EvilsInterrupt @  18.8.2010,  09:41 Найти цитируемый пост)
но тогда я лишусь проверки других функций, а не вот этого  конкретного места. Как сказать компиллеру (MSVC 2008/2010) что именно в этом месте, а я отлично  шарю чего  делаю и все вычислил для этого ?

Код

#pragma warning(suppress: 4996)


Автор: EvilsInterrupt 18.8.2010, 09:52
Всем спасибо, был допущен некоторый баг ;))) + это отключение варнинга, вопрос решен! ;)

Автор: azesmcar 18.8.2010, 10:02
Пожалуйста.
Цитата(EvilsInterrupt @  18.8.2010,  09:28 Найти цитируемый пост)
Второстепенный:
  typedef   typename VecT_t::iterator   VecTItr_t;
Почему в этом месте компиллер нуждается в написании ключевого слова "typename" ? 

typename тут нужен для того, чтобы dependant типы распознавались.

Автор: EvilsInterrupt 18.8.2010, 11:30
Надеюсь не буду слишком назойливым если прошу что следует понимать под термином "dependant типы"  ? ;)

Автор: mes 18.8.2010, 11:34
зависимые от аргумента шаблона

Добавлено через 8 минут и 1 секунду
вот пример когда t в одном случае является типом, а в другом значением
http://codepad.org/7Wx0rYd5
а компилятор должен заранее знать, как именно квалифицировать зависимое имя.

Автор: Леопольд 18.8.2010, 11:43
Цитата(EvilsInterrupt @  18.8.2010,  11:30 Найти цитируемый пост)
Надеюсь не буду слишком назойливым если прошу что следует понимать под термином "dependant типы"  ? ;) 
http://en.wikipedia.org/wiki/Typename#A_method_for_indicating_that_a_dependent_name_is_a_type

Добавлено @ 11:49
EvilsInterrupt, зачем использовать приведения типов от std::size_t к знаковому int? Если же оно необходимо, тогда правилом хорошего тона считается использовать приведение С++ а не С. Т.е. static_cast, в данном случае.

Автор: EvilsInterrupt 18.8.2010, 12:08
Леопольд,
>>зачем использовать приведения типов от std::size_t к знаковому int
ну по идеологии size_t это тип хранящий разность двух указателей, чтобы мог вместиться любой указатель, который на любой платформе как правило равен размеру регистра, то этот тип тоже приравниваются к этому размеру регистра . В моем же случае хватит и int и предполагается что чел юзающий буфер, врядли будет внем хранить на 2 ГБ ))) думаю максимум 5 МБ т.е. инт за глаза! ;)

>>тогда правилом хорошего тона считается использовать приведение С++ а не С. Т.е. static_cast, в данном случае.
к нему еще привыкать надо, а я еще думаю в стиле С ))) но согласен, укор правилен ;)

Автор: mes 18.8.2010, 12:17
Цитата(EvilsInterrupt @  18.8.2010,  11:08 Найти цитируемый пост)
 В моем же случае хватит и int и предполагается что чел юзающий буфер, врядли будет внем хранить на 2 ГБ ))) думаю максимум 5 МБ т.е. инт за глаза! ;)

если делаете шаблон, то зачем делать предположения за юзера ?! позвольте пользователю самому настроить необходимое.
а чтоб не передавать кучу параметров в шаблон, погуглите насчет traits.
 В двух словах это такая структура, в которой описаны все типы и зависимости необходимые для настройки шаблона.
smile

Автор: EvilsInterrupt 18.8.2010, 12:36
mes, 
Вы об http://forum.sources.ru/index.php?showtopic=86507 ?
>>если делаете шаблон, то зачем делать предположения за юзера ?!
Затем чтоб лишний раз подумал прежде чем что-то сделать! Лично этот класс, пусть и шаблонный расчитан на использование мною и для моих нужд. В случае если он кому-то приглянется, чтобы четко знал что тут все нужно еще раз хорошо все просмотреть ;)

Автор: mes 18.8.2010, 12:43
Цитата(EvilsInterrupt @  18.8.2010,  11:36 Найти цитируемый пост)
Вы об этом ?

smile

Цитата(EvilsInterrupt @  18.8.2010,  11:36 Найти цитируемый пост)
Лично этот класс, пусть и шаблонный расчитан на использование мною и для моих нужд

Под пользователем подразумевается любой пользователь, и прежде всего Вы сами  smile

один раз определив нужный тип, Вы уже не будете путаться int там должен быть или не int
smile

Цитата(EvilsInterrupt @  18.8.2010,  11:36 Найти цитируемый пост)
В случае если он кому-то приглянется, 

не надо думать о других, делайте так, чтоб Вам было удобно и приятно .. 




Автор: xvr 19.8.2010, 11:43
Цитата(EvilsInterrupt @  18.8.2010,  12:08 Найти цитируемый пост)
ну по идеологии size_t это тип хранящий разность двух указателей,
Если быть точным, то size_t это разрядность размера любого объекта, а для разности указателей есть ptrdiff_t

Автор: EvilsInterrupt 19.8.2010, 12:11
xvr, Любого из тривививальных так сказать? ;))) т.е пользовательские сюда уже не полезут ;)

Автор: xvr 19.8.2010, 12:20
Цитата(EvilsInterrupt @ 19.8.2010,  12:11)
xvr, Любого из тривививальных так сказать? ;))) т.е пользовательские сюда уже не полезут ;)

Совсем любого. Переменная типа size_t способна вместить число, равное размеру чего угодно в памяти (т.е. проще говоря почти размеру виртуального адресного пространства). При этом она беззнаковая, т.к. объектов с отрицательным размером не бывает.

Автор: EvilsInterrupt 19.8.2010, 14:02
xvr, Хорошо,но какой будет нативный тип , при котором будут наиболее эффективными вычисления? Если не int то что? Не он потому что на некоторых платформах, он должен быть 64-бита при компиляции под 64, а он все еще 32 ! ;)

http://www.viva64.com/content/articles/64-bit-development/?f=size_t_and_ptrdiff_t_rus.html&lang=ru&content=64-bit-development

Автор: xvr 20.8.2010, 09:43
Цитата(EvilsInterrupt @ 19.8.2010,  14:02)
xvr, Хорошо,но какой будет нативный тип , при котором будут наиболее эффективными вычисления? Если не int то что? 

int_fast32_t из stdint.4 (C99)
Цитата

Не он потому что на некоторых платформах, он должен быть 64-бита при компиляции под 64, а он все еще 32 ! ;)
Это так исторически сложилось  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)