为什么我不能重新分配以前在 C++ 堆栈上分配的变量('Frame' 的复制赋值运算符被隐式删除)?

Why can't I reassign a variable that was formerly allocated on the stack in C++ (copy assignment operator of 'Frame' is implicitly deleted)?

我有以下设置:

struct Frame {
    Frame(vector<Region> regions_)
        : regions(regions_){}
    const vector<Region> regions;
};

现在,在我的代码的不同部分,我想创建一个 vector<Frame> 并创建以下 for 循环:

vector<Frame> shot;
Frame currentFrame = generateRandomFrame();
for (int i = 0; i < length; i++) {
    shot.push_back(currentFrame);
    currentFrame = generateNextFrame(currentFrame); // this line gives the error
}

其中 generateNextFrame 具有以下签名: Frame FrameGenerator::generateNextFrame(Frame previousFrame)

现在,这段代码无法编译并出现以下错误:

copy assignment operator of 'Frame' is implicitly 
deleted because field 'regions' has no copy assignment 
operator const vector<Region> regions;

现在,我不完全理解这个错误信息。我强烈认为这与 currentFrame 分配在 堆栈 而不是 上有关,因此我可以'只是重新分配变量。然而,作为 C++ 的新手,我不熟悉如何处理这些情况。我应该在这里改用指针并尝试在堆上分配 currentFrame 吗?

明确地说,我的目标是生成一系列 frames(这取决于之前的一些帧)。谁能给我指出正确的方向?

更新: 非常感谢评论中的所有提示,我现在明白问题出在我将 regions 声明为 const。我重写了代码以使用指针而不是堆变量,现在看起来像这样:

vector<Frame> shot;
Frame currentFrame = generateRandomFrame();
Frame *currentFramePtr = &currentFrame; // the first frame in the shot is random
for (int i = 0; i < length; i++) {
    shot.push_back(*currentFramePtr);
    Frame tmpFrame = generateNextFrame(*currentFramePtr);
    currentFramePtr = &tmpFrame; 
}

这段代码现在可以编译,但是它仍然没有达到我想要的效果。根据我的理解,它现在应该可以工作了,因为我将 currentFrame 存储在一个指针中,所以我可以很容易地用我创建的新对象覆盖它。但似乎仍然存在一个错误,帧生成没有按预期工作(即生成的任何新帧都带有 0 个区域,而区域数量应与前一帧相同)。任何人都可以看到我的代码的这个更新版本有什么问题吗?

您的 struct 声明了一个 const 成员,由于 const 成员没有复制赋值运算符,这会强制编译器隐式删除默认的复制赋值运算符。

下面的代码替换了您从示例中省略的位,并展示了如何生成一堆 Frame * 而不是 Frame。基本上,它是您编译问题的解决方法,但如果您的代码需要堆栈使用或者您必须重构太多,它可能不适合您的特定需求。

#include <iostream>
#include <vector>

struct Region{};

struct Frame {
    Frame(std::vector<Region> regions_)
    : regions(regions_){}
    const std::vector<Region> regions;
};

int main(int argc, const char * argv[]) {

    std::vector<Frame *> shot;
    Frame * currentFrame = new Frame((std::vector<Region>()));
    for (int i = 0; i < 10; i++) {
        shot.push_back(currentFrame);
        currentFrame = new Frame(std::vector<Region>());
    }

    return 0;
}

另请注意: how to use const_cast? - const_cast 对你不起作用,会导致 UB。以防万一;)

如果你绝对坚持保持 regions 常量,并有“赋值”,你可以销毁现有的 Frame 并在原地创建一个新的。

std::vector<Frame> shot;
Frame currentFrame = generateRandomFrame();
for (int i = 0; i < length; i++) {
    shot.push_back(currentFrame);
    currentFrame.~Frame();
    new (&currentFrame) Frame(generateNextFrame(shot.back()));
}

然而,更简单的方法是不重新分配任何东西

std::vector<Frame> shot;
shot.push_back(generateRandomFrame());
for (int i = 1; i < length; i++) {
    shot.push_back(generateNextFrame(shot.back()));
}