Иногда полезно использовать начальный адрес std::vector
и временно обработка, которые обращаются как адрес регулярно выделяемого буфера.
Например, замените это:
char* buf = new char[size];
fillTheBuffer(buf, size);
useTheBuffer(buf, size);
delete[] buf;
С этим:
vector<char> buf(size);
fillTheBuffer(&buf[0], size);
useTheBuffer(&buf[0], size);
Преимущество этого состоит, конечно в том, что буфер освобожден автоматически, и я не должен волноваться о delete[]
.
Проблема, которую я имею с этим, состоит в том когда размер == 0. В этом случае первая версия работает хорошо. Пустой буфер "выделяется", и последующие функции ничего не делают размер, они получают размер == 0.
Вторая версия однако перестала работать если размер == 0 начиная с вызова buf[0]
может справедливо содержать утверждение это 0 < size
.
Так есть ли альтернатива идиоме &buf[0]
это возвращает адрес запуска вектора, даже если вектор пуст?
Я также рассмотрел использование buf.begin()
но согласно стандарту это, как даже гарантируют, не возвратит указатель.
Я думаю, вам просто нужно проверить.
Возможно, служебная функция:
template <class T, class Alloc>
T* data(std::vector<T, Alloc>& vec)
{
return vec.empty() ? 0 : &vec[0];
}
template <class T, class Alloc>
const T* data(const std::vector<T, Alloc>& vec)
{
return vec.empty() ? 0 : &vec[0];
}
Думаю, в любом случае вы должны быть в безопасности. Я считаю, что разница между vector :: operator [int] и vector :: at (int) заключается в том, что перегрузка оператора [] конкретно , а не выполняет проверку границ. Использование buf [0] не должно содержать утверждений!
Для этого нет функции, хотя std :: basic_string
имеет data ()
, который делает именно то, что вам нужно.
Вам нужно будет использовать что-то вроде buf.size ()? & Buf [0]: 0;
Если вы можете изменить fillTheBuffer и useTheBuffer для получения пары итераторов, тогда вы решите проблему так же, как ее решила стандартная библиотека.