Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert elements into a multidimensional vector of unique pointers?

I have a Turn class with a _rounds private member. _rounds is a bidimensional std vector of std unique pointers to another class called Animation:

Turn.h

std::vector<std::vector<std::unique_ptr<Animation>>> _rounds;   

Animation.h

class Animation
{
public:
    enum Type
    {
        MOVE,
        ATTACK,
        DIE,
        FADEOUT,
        MAX_TYPES
    };

//Constructors
Animation();        
Animation(Creature* creature, Animation::Type type, GameManager* gameManager, const std::function<void()> callback = nullptr);

//Getters   
const int& getOriginRowClipsIndex() { return _originRowClipsIndex; }
bool& getFinished() { return _finished; }
Type& getType() { return _type; }
Creature& getCreature() { return *_creature; }

//Setters       
void setOriginRowClipsIndex(int originRowClipsIndex) { _originRowClipsIndex = originRowClipsIndex; }

void animate(); 
void reset();
SDL_Rect* getClip(int index) {      
    return &_clips[index];      
}

private:
    GameManager* _gameManager;
    Creature * _creature;
    bool _finished;
    unsigned int _clipIndex;
    int _frequency;
    int _originRowClipsIndex; //Origin index of anim clips.     
    std::vector<SDL_Rect> _clips;   
    Type _type; 
    std::function<void()> _callback;
};
#endif

I dynamically allocate the Animations from various points of my code and try to add them to Turn _rounds with a Turn public method called addAnimation like this:

auto animation = std::make_unique<Animation>(this, Animation::Type::MOVE, _gameManager);            
turn.addAnimation(std::move(animation)); //Use move to make addAnimation take ownership of the animation.

Then the Turn addAnimation() method tries to add the Animations to its member _rounds as follows:

Turn.cpp

void Turn::addAnimation(std::unique_ptr<Animation> animation)
{   
unsigned int roundIndex;

//Set animating to true when the first animation is added to the first animation round. TODO: Move this elsewhere.
if (_rounds.size() == 0)
    _animating = true;

if (animation->getType() == Animation::MOVE) { //All move animations go on first round.
    roundIndex = 0;
    if (animation->getCreature().isPlayer()) //Set _playerMoves to be able to set monster attacks on the correct round index.
    {
        _playerMoves = true;
    }
}else if (animation->getType() == Animation::ATTACK) 
{
    roundIndex = _playerMoves ? _nAttacks + 1 : _nAttacks;
    _nAttacks++; //Increment number of attacks.     
}
else
{
    roundIndex = _rounds.size();
}

//Check if the wanted round index already exists and create if not.
if (roundIndex >= _rounds.size()) {
    //_rounds.push_back({});
    _rounds.resize(_rounds.size() + 1);
}

//Add animation to animations vector.
_rounds[roundIndex].push_back(std::move(animation));
}

However I am getting an error saying that I am trying to reference a deleted function as if I was trying to use the deleted copy constructor or something.

> 1>------ Build started: Project: Roguelike, Configuration: Debug Win32 ------
1>  Turn.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(637): error C2280: 'std::unique_ptr<Animation,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
1>          with
1>          [
1>              _Ty=Animation
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1435): note: see declaration of 'std::unique_ptr<Animation,std::default_delete<_Ty>>::unique_ptr'
1>          with
1>          [
1>              _Ty=Animation
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(755): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,std::unique_ptr<Animation,std::default_delete<Animation>>&>(_Objty *,std::unique_ptr<Animation,std::default_delete<Animation>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<Animation,std::default_delete<Animation>>,
1>              _Objty=std::unique_ptr<Animation,std::default_delete<Animation>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(755): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,std::unique_ptr<Animation,std::default_delete<Animation>>&>(_Objty *,std::unique_ptr<Animation,std::default_delete<Animation>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<Animation,std::default_delete<Animation>>,
1>              _Objty=std::unique_ptr<Animation,std::default_delete<Animation>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(894): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,std::unique_ptr<Animation,std::default_delete<Animation>>&>(std::allocator<_Ty> &,_Objty *,std::unique_ptr<Animation,std::default_delete<Animation>> &)' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::unique_ptr<Animation,std::default_delete<Animation>>>,
1>              _Ty=std::unique_ptr<Animation,std::default_delete<Animation>>,
1>              _Objty=std::unique_ptr<Animation,std::default_delete<Animation>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(893): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,std::unique_ptr<Animation,std::default_delete<Animation>>&>(std::allocator<_Ty> &,_Objty *,std::unique_ptr<Animation,std::default_delete<Animation>> &)' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::unique_ptr<Animation,std::default_delete<Animation>>>,
1>              _Ty=std::unique_ptr<Animation,std::default_delete<Animation>>,
1>              _Objty=std::unique_ptr<Animation,std::default_delete<Animation>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(1286): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<std::unique_ptr<Animation,std::default_delete<Animation>>,std::unique_ptr<Animation,std::default_delete<Animation>>&>(_Ty *,std::unique_ptr<Animation,std::default_delete<Animation>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<Animation,std::default_delete<Animation>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(1285): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<std::unique_ptr<Animation,std::default_delete<Animation>>,std::unique_ptr<Animation,std::default_delete<Animation>>&>(_Ty *,std::unique_ptr<Animation,std::default_delete<Animation>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<Animation,std::default_delete<Animation>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(1278): note: while compiling class template member function 'void std::vector<std::unique_ptr<Animation,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>::push_back(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)'
1>          with
1>          [
1>              _Ty=Animation
1>          ]
1>  c:\cpp\roguelike\roguelike\turn.cpp(44): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<Animation,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>::push_back(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' being compiled
1>          with
1>          [
1>              _Ty=Animation
1>          ]
1>  c:\cpp\roguelike\roguelike\turn.cpp(44): note: see reference to class template instantiation 'std::vector<std::unique_ptr<Animation,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>' being compiled
1>          with
1>          [
1>              _Ty=Animation
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

The only point of my code that appears at the end of the long chain of template errors is at the push_back to the unique pointers vector of addAnimation.

If I try to compile a simplified case I have no problem even adding custom constructors to Animation class:

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <memory>

class Animation
{
    int _animation_value;
public:
    Animation() {};
    Animation(int animation_value)
        : _animation_value(animation_value)
    {}
};

class Turn
{
    std::vector<std::vector<std::unique_ptr<Animation>>> _rounds;
public:
    void addAnimation(std::unique_ptr<Animation> round)
    {
        _rounds.resize(_rounds.size() + 1);
        _rounds[0].push_back(std::move(round));
    }
};

class Other
{
public:
    void foo()
    {
        auto x = std::make_unique<Animation>(7);
        Turn turn;
        turn.addAnimation(std::move(x));
    }
};

int main()
{
    Other other;
    other.foo();        
    return 0;
}

Any help?

like image 938
Harley Fuagras Avatar asked Apr 25 '17 11:04

Harley Fuagras


1 Answers

are you copying your turn class anywhere in the code? because, as stated in the comments, there seems to be no error in the addAnimation function itself. so maybe you generate some code where the whole turn class gets copied and so the vector of vectors of unique pointers wants to make a copy?

like image 65
phön Avatar answered Oct 26 '22 00:10

phön