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, чтобы взять пару итераторов, то вы будете решать проблему так же, как стандартная библиотека решила ее.