代码之家  ›  专栏  ›  技术社区  ›  ZeroZ30o

std::包含原子的类的向量

  •  1
  • ZeroZ30o  · 技术社区  · 6 年前

    我试图创建一个包含类实例的向量,该类反过来包含(除其他外)std::atomic。

    我尝试了以下几种:

    • 如果没有指定复制构造函数,编译器将给出一个关于删除构造函数的错误。

    如果指定了复制构造函数,我尝试了两件事:

    • 对于foo(foo&other),它会抱怨没有找到foo的复制构造函数。

      编辑:复制构造函数是foo(foo&other):原子的(other.atomic.load()){}

    • 对于foo(const-foo&other),它会抱怨std::atomic没有const-copy构造函数。

      编辑:复制构造函数是foo(const foo&other):原子的(other.atomic.load()){}

    我完全不知道如何解决这个问题,所以非常感谢您的帮助

    1 回复  |  直到 6 年前
        1
  •  4
  •   Angew is no longer proud of SO    6 年前

    std::atomic 设计上既不可复制也不可移动。上的操作 std::vector 这导致它重新分配,要求它的元素至少是可移动的。因此,您有以下选项:

    • 停止存储 std::原子 在element类中。也许是 std::unique_ptr<std::atomic> 可以改用。
    • 停止将元素类直接存储在向量中,存储 std::unique_ptr<ElementClass> 相反(正如@Richard Criten在评论中所建议的)。
    • 为类编写一个复制或移动构造函数和赋值运算符,这将以某种方式解决 std::原子
    • 为类提供虚拟复制/移动操作以满足编译器的要求。然后,使用 reserve ,然后仅使用附加元素(最大为预先分配的大小)、访问元素或从末尾删除元素的函数;中间没有插入或删除。这样,虚拟操作就永远不会真正被调用。

      鉴于这种方法的脆弱性,我建议采取两种预防措施:

      1. 让假人投掷,以便尽快捕获任何违反“不调整大小”要求的情况。
      2. 不使用 标准::矢量 直接,但用你自己的包装 NonResizableVector<T> 具有适当限制的接口,并对其进行大量记录。

    您应该(甚至可以)使用哪一个取决于您的类实际做了什么。