lefti
lefti

Reputation: 268

error C2280: attempting to reference a deleted function (trying to call vector.erase)

I'm new to C++. I'm developing a breakout-clone with SFML and Box2D, and I get this error when compiling. Details of the error:

c:\program files (x86)\visual studio express 2013\vc\include\xutility(2420): error C2280: 'Tile &Tile::operator =(const Tile &)' : attempting to reference a deleted function
c:\users\harry\documents\visual studio 2013\projects\cpp-breakout\cpp-breakout\entities\tile.hpp(27) : compiler has generated 'Tile::operator =' here

The error comes when I try to erase Tile objects from a std::vector< Tile> with vector.erase.

Tile.h

class Tile : public Entity {
public:
    Tile(b2World* world, float posX, float posY);
    void draw(sf::RenderWindow& window);

    const float PTM_RATIO = 32.f;
    const int HALF_WIDTH = 32;
    const int HALF_HEIGHT = 16;
    int armor;
    bool flaggedToErase = false;

    b2Body* tileBody;
    sf::Sprite sprite;
};

Tile.cpp

Tile::Tile(b2World* world, float posX, float posY)
{
    // Define a body.
    b2BodyDef tileBodyDef;
    tileBodyDef.type = b2_staticBody;
    tileBodyDef.position.Set((posX + HALF_WIDTH) / PTM_RATIO, (posY + HALF_HEIGHT) / PTM_RATIO);

    // Use the body definition to create the actual body instance.
    tileBody = world->CreateBody(&tileBodyDef);
    tileBody->SetUserData(this);
    // Define shape.
    b2PolygonShape tileShape;
    tileShape.SetAsBox(HALF_WIDTH / PTM_RATIO, HALF_HEIGHT / PTM_RATIO);

    // Define fixture.
    b2FixtureDef tileFixtureDef;
    tileFixtureDef.shape = &tileShape;
    tileFixtureDef.density = 10.0f;
    tileFixtureDef.restitution = 0.1f;
    tileFixtureDef.friction = 0.0f;
    //tileFixtureDef.isSensor = true;

    bUserData* bud = new bUserData;
    bud->entityType = TILE;
    tileFixtureDef.userData = bud;

    // Create fixture.
    tileBody->CreateFixture(&tileFixtureDef);
}

I push Tiles to the vector in

Level.cpp

std::vector<Tile> solidTiles;

void Level::loadLevel(b2World* world) {
    // Loop through the map and set the tile position and sprites to the tiles.
    for(unsigned int i = 0; i < map.size(); i++) {
        for(unsigned int j = 0; j < map[i].size(); j++) {
            // Set sprites to the tiles in every grid cell which is not -1,-1.
            if(map[i][j].x != -1 && map[i][j].y != -1) {
                Tile tempTile(world, j * TILE_WIDTH, i * TILE_HEIGHT);
                tempTile.sprite = tiles;
                tempTile.sprite.setOrigin(sf::Vector2f(HALF_WIDTH, HALF_HEIGHT));
                tempTile.sprite.setTextureRect(sf::IntRect(map[i][j].x * TILE_WIDTH, map[i][j].y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT));
                tempTile.sprite.setPosition(sf::Vector2f(tempTile.tileBody->GetPosition().x * PTM_RATIO, tempTile.tileBody->GetPosition().y * PTM_RATIO));
                solidTiles.push_back(tempTile);
            }
        }
    }
}

And I try to erase the tiles in

PlayState.cpp

void PlayState::removeSprites() {
    for(unsigned int i = 0; i < level1.solidTiles.size(); i++) {
        if(level1.solidTiles[i].flaggedToErase == true) {
            level1.solidTiles.erase(level1.solidTiles.begin() + i);
        }
    }
}

Is the problem somehow related to move constructor/assignment?

Upvotes: 2

Views: 9653

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310910

As the class Tile has a const data members then its implicitly defined by the compiler copy assignment operator is defined as deleted.

You have yourself to define the copy assignment operator explicitly.

Upvotes: 9

Quentin
Quentin

Reputation: 63114

The error clearly mentions Tile &Tile::operator =(const Tile &), so it's about the assignment operator, not the move-assignment operator. You need to implement it for Tile. You're also missing Tile's copy-constructor.

Quote from here :

The implicitly-declared or defaulted copy assignment operator for class T is defined as deleted in any of the following is true:

  • T has a non-static data member that is const
  • T has a non-static data member of a reference type.
  • T has a non-static data member that cannot be copy-assigned (has deleted, inaccessible, or ambiguous copy assignment operator)
  • T has direct or virtual base class that cannot be copy-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has a user-declared move constructor
  • T has a user-declared move assignment operator

Upvotes: 0

Related Questions