将包含循环缓冲区的类添加到 Vector

Posted

技术标签:

【中文标题】将包含循环缓冲区的类添加到 Vector【英文标题】:Add class containing a circular buffer to Vector 【发布时间】:2021-08-27 20:30:54 【问题描述】:

我正在尝试创建一个充满类对象的向量,并且类对象包含循环缓冲区作为它们的成员之一。我遇到了这个错误:

In file included from .pio/libdeps/teensy40/Vector/src/Vector.h:95:0,
                 from src/main.cpp:2:
.pio/libdeps/teensy40/Vector/src/Vector/VectorDefinitions.h: In instantiation of 'void Vector<T>::push_back(const T&) [with T = Node]':
src/main.cpp:25:27:   required from here
.pio/libdeps/teensy40/Vector/src/Vector/VectorDefinitions.h:162:22: error: use of deleted function 'Node& Node::operator=(const Node&)'
     values_[size_++] = value;
                      ^
src/main.cpp:5:7: note: 'Node& Node::operator=(const Node&)' is implicitly deleted because the default definition would be ill-formed:
 class Node
       ^
src/main.cpp:5:7: error: use of deleted function 'CircularBuffer<T, S, IT>& CircularBuffer<T, S, IT>::operator=(const CircularBuffer<T, S, IT>&) [with T = long unsigned int; unsigned int S = 100u; IT = unsigned char]'
In file included from src/main.cpp:3:0:
.pio/libdeps/teensy40/CircularBuffer/CircularBuffer.h:64:18: note: declared here
  CircularBuffer& operator=(const CircularBuffer&) = delete;
                  ^
*** [.pio/build/teensy40/src/main.cpp.o] Error 1
======================================== [FAILED] Took 0.99 seconds ========================================

我创建了一个程序,它是我可以复制错误的最少代码:

#include <Arduino.h>
#include <Vector.h>
#include <CircularBuffer.h>

class Node

  CircularBuffer<uint32_t, 100> RTTSamplesBuffer;
;

// Vector to hold the nodes we currently have saved
Vector<Node> Nodes;
// This stuff is used in setup to make the vector not use dynamic allocation
// This version of the Vector library is special for arduino so it is not
// dynamically allocating the vector to prevent filling the controllers memory
const int NODE_COUNT_MAX = 20;
Node storage_array[NODE_COUNT_MAX];

void setup()

  Serial.begin(115200);
  // Point the vector to it's storage location.
  Nodes.setStorage(storage_array);

  while (!Serial)
    ;

  // Create Node I want to add to the vector
  Node testNode;

  // Try and add the Node to the vector.
  Nodes.push_back(testNode);

  while (1)
    ;


void loop()

  // put your main code here, to run repeatedly:


我使用this 库作为向量,因为它与Arduino 兼容并且不会填满内存,我使用this 库作为循环缓冲区。谢谢!

【问题讨论】:

那个循环缓冲区类不喜欢移动。一点也不。 link to github 对于容器类型来说,这似乎有点过分...... 而且 Vector 不支持emplace()...同时使用这两个类可能是个坏主意... 我试图让该类包含一个数据缓冲区,以及其他值,例如地址、离开时间等。有没有更好的方法来保存数据?我不想每次添加新数据点时都遍历数组 @callyalater 不,存储已设置:Nodes.setStorage(storage_array);。此外,那个向量类很奇怪。存储实际上是一个完全构造的对象列表,这些对象根据需要重新分配,而不是您所期望的对齐存储.. @Frank 我后来看到了,这就是我删除评论的原因。尽管在查看实现时,似乎在Node 中隐式删除复制构造函数并为CircularBuffer 显式删除,尝试执行push_back(不将对象移动到向量中,而不是复制它)将导致错误。不过我不完全确定 【参考方案1】:

看循环缓冲区的代码:

    CircularBuffer(const CircularBuffer&) = delete;
    CircularBuffer(CircularBuffer&&) = delete;
    CircularBuffer& operator=(const CircularBuffer&) = delete;
    CircularBuffer& operator=(CircularBuffer&&) = delete;

这意味着循环缓冲区一旦分配,就不能以任何方式移动或复制。它保持在原来的位置,这也适用于将其中之一作为成员的任何类型。

添加一个间接级别,以便 CircularBuffers 只被引用,而不是被复制,这将使您摆脱困境。

大概是这样的:

class Node

  using buffer_type = CircularBuffer<uint32_t, 100>;

  buffer_type* RTTSamplesBuffer = nullptr;

public:
  set_buffer(buffer_type* b) 
    RTTSamplesBuffer = b;
  
;

const int NODE_COUNT_MAX = 20;
Node storage_array[NODE_COUNT_MAX];
Node::buffer_type buffers[NODE_COUNT_MAX];

void setup()

  for(int i=0; i<NODE_COUNT_MAX; ++i) 
    storage_array[i].set_buffer(&buffers[i]);
  

  // ...

通常,这就是“应该”对 0/3/5 规则进行大量讨论的地方。但是,只要这些是指向全局分配对象的指针,就不是绝对必要的。

【讨论】:

太棒了,我试试看。如果删除向量内的类会导致问题吗? 这个解决方案是否比用向量替换循环缓冲区更好?

以上是关于将包含循环缓冲区的类添加到 Vector的主要内容,如果未能解决你的问题,请参考以下文章

顶点以及顶点缓冲区

顶点缓冲区数据的内存管理

将 char* 推送到向量时出现问题,但在每次迭代后,它会将指向相同值缓冲区的指针添加到向量中 [已解决]

C++ 中的高效循环缓冲区,将传递给 C 风格的数组函数参数

OpenGL 帧缓冲函数不能在单独的类中完全工作

java 之前的安全的类回顾,以及以后需要线程安全时使用哪些类