编译器调用复制运算符而不是移动运算符

Compiler calls copy operator instead of move operator

确实事先在这里找到了一个确切的问题,但我没有相同的问题原因(或者至少我这么认为)。我的 AnimatedSprite class 有一个 Timer 成员,该成员不可复制(明确删除了 copy ctor 和 operator= )。然而,当我尝试在其他 class 的 ctor 中初始化精灵时,我收到一条错误消息,提示我正在引用已删除的复制运算符 =.

Timer.h:

#pragma once
#include <set>

class Timer
{
public:
    Timer() :
        currentTime_{0},
        expirationTime_{0}
    {}
    Timer(unsigned expirationTime) :
        currentTime_{ expirationTime },
        expirationTime_{ expirationTime }
    {
        timers_.insert(this);
    }

    ~Timer() {
        timers_.erase(this);
    }
    // Here
    Timer(const Timer& other) = delete;
    Timer& operator=(const Timer& other) = delete;

    Timer(Timer&& other) = default;
    Timer& operator=(Timer&& other) = default;


    //   Assumes the user knows if |this| is active or not
    unsigned currentTime() const { return currentTime_; }

    bool active() const { return currentTime_ < expirationTime_; }
    bool expired() const { return !active(); }
    void reset() { currentTime_ = 0; }
    void disable() { currentTime_ = expirationTime_; }


    static void updateAll(unsigned elapsedTime);

private:

    void update(unsigned elapsedTime) {
        if (active()) {
            currentTime_ += elapsedTime;
        }
    }


    static std::set<Timer*> timers_;
    unsigned currentTime_;
    const unsigned expirationTime_;

};

AnimatedSprite.h

#pragma once
#include <vector>
#include <map>
#include "Globals.h"
#include "Sprite.h"
#include "Timer.h"


class Sprite;
class Graphics;

class AnimatedSprite : public Sprite
{
public:
    AnimatedSprite() = default;
    AnimatedSprite(Graphics& graphics, const std::string& filePath,
        int sourceX, int sourceY, int width, int height,
        unsigned frameLength, unsigned frameCount);

    void update(bool once = false);
    const bool completedOnce() const { return once_; }

private:

    Timer frameTimer_;
    unsigned currentFrame_{ 0 };
    unsigned totalFrames_;
    bool once_{ false };    //  if true, plays animation once
};

然后我这样做:

sprite_ = AnimatedSprite( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );

这里不应该调用移动运算符吗?我的 RHS 不是在右值上方的行中吗?

关于你的 AnimatedSprite 的一些东西阻止了它的移动。一旦消除,它就会尝试复制。你得到了你的错误。

可能 Sprite 中的某些东西阻止了它被移动。或 Timer 中的内容; =default 如果你不能移动东西,可以变成 =delete

我使用的一种技术是注入关于此类假设的静态断言。

static_assert( std::is_move_assignable<Sprite>{}, "Cannot move Sprite" );
static_assert( std::is_move_constructible<Sprite>{}, "Cannot move Sprite" );
static_assert( std::is_move_assignable<Timer>{}, "Cannot move Timer" );
static_assert( std::is_move_constructible<Timer>{}, "Cannot move Timer" );

现在,使用我的脑内编译器,我可以看到:

const unsigned expirationTime_;

将阻止 Timer 上的移动分配。

备份到设计:

sprite_ = AnimatedSprite( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );

分配一个当前动画精灵在另一个之上是否有意义?

我怀疑。

我会 =delete operator=(&&).

sprite_ 替换为 std::optional<AnimatedSprite>,然后执行:

sprite_.emplace( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );

这通常比"sprite that is in a state that isn't a sprite".

理智得多