C++: получение адреса начала std:: vector?
иногда полезно использовать начальный адрес 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[]
.
проблема, с которой я сталкиваюсь, заключается в том, когда size == 0. В этом случае работает первая версия ладно. Пустой буфер "выделяется", а последующие функции ничего не делают, размер они получают size == 0.
Вторая версия, однако, терпит неудачу, если size == 0 с момента вызова buf[0]
может справедливо содержать утверждение, что 0 < size
.
Итак, есть альтернатива идиоме &buf[0]
, которая возвращает адрес начала вектора, даже если вектор пуст?
Я также рассматривал возможность использования buf.begin()
но согласно стандарту даже не гарантировано, что возвратит указатель.
4 ответов
Я думаю, вам просто нужно проверить.
возможно, функция полезности:
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];
}
для этого нет функции, хотя std::basic_string
и data()
что делает именно то, что вам нужно.
вам придется использовать что-то вроде buf.size()?&buf[0]:0;
Я думаю, вы должны быть в безопасности в любом случае. Я считаю, что различия между vector::operator[int] и vector:: at(int) заключаются в том, что перегрузка оператора [] специально делает не выполнить проверку границ. Использование buf[0] должно быть свободным от утверждений!
Если вы можете изменить fillTheBuffer и useTheBuffer, чтобы взять пару итераторов, то вы будете решать проблему так же, как стандартная библиотека решила ее.