在不复制的情况下构造一个范围内的向量

Pat*_*ryk 5 c++ vector placement-new stdvector allocator

我有一个类包装了大量的网络数据包字节。该类实现一个队列并提供(除其他外)front()函数,该函数返回构成队列中最旧数据包的字节常量向量。

class Buffer{
  unsigned char data[65536];
  unsigned int offset;
  unsigned int length;
  [...]//other fields for maintaining write ptr etc.

public:
  const std::vector<unsigned char> front(){
    return std::vector<unsigned char>(data + offset, data + offset + length);
  }

  //other methods for accessing the queue like
  //pop(), push(), clean() and so forth...
  [...]
}
Run Code Online (Sandbox Code Playgroud)

上述front()函数实现的性能受到从当前数据包占据的范围内不必要的复制字节的影响。由于向量是常量,因此无需复制数据。我想要的是在已经存储在缓冲区中的数据上创建一个向量。当然,向量的析构函数不应该释放内存。

Sea*_*ean 0

如果您希望避免不必要的复制,那么您需要返回数据视图。您可以提供一front_begin()front_end()函数:

const char *front_begin() const
{
  return data + offset;
}

const char *front_end() const
{
  return data + offset + length;
}
Run Code Online (Sandbox Code Playgroud)

或者写一个包装类:

class Data
{
private:
  const char *m_Begin;
  const char *m_End;

public:
  Data(const char *begin, const char *end) : m_Begin(begin), m_End(end)
  {
  }

  const char *begin() const
  {
    return m_Begin;
  }

  const char *end() const
  {
    return m_End;
  }
}
Run Code Online (Sandbox Code Playgroud)

并让你的front()方法返回其中之一:

Data front()
{
  return Data(data + offset, data + offset + length)
}
Run Code Online (Sandbox Code Playgroud)

Data如果您使用的是 C++11,那么您可以在基于范围的 for 循环中使用实例:

Data data = buffer.front();
for(char c : data)
{
  // Do something with the data
}
Run Code Online (Sandbox Code Playgroud)