Reputation:
I'm playing around with the different smart pointers and ran into a problem.
I have a Environment
abstract class and a ground class which inherits Environment
:
class Ground : public Environment
{
protected:
std::string type;
int damage;
public:
Ground() : Environment()
{
this->type = "ground";
}
virtual void SetDamage(int _damage)
{
this->damage = _damage*5;
}
virtual std::string& GetType()
{
return this->type;
}
virtual int GetDamage()
{
return this->damage-10;
}
virtual ~Ground(){}
};
I also have a Dirt
class which inherits the Ground
class:
class Dirt : public Ground
{
public:
Dirt() : Ground()
{
this->type = "dirt";
}
void SetDamage(int _damage)
{
this->damage = _damage*6;
}
int GetDamage()
{
return this->damage-20;
}
~Dirt()
{
}
private:
};
Now if i want to use it inside a std::vector
like this:
std::vector<std::unique_ptr<Ground>> listGround;
std::unique_ptr<Ground> ground(new Ground());
listGround.push_back(ground);
std::unique_ptr<Dirt> dirt(new Dirt());
listGround.push_back(dirt); // FAIL
for (auto i = listGround.begin(); i != listGround.end(); i++)
{
(*i)->SetDamage(80);
std::cout << (*i)->GetType() << " " << (*i)->GetDamage() << std::endl;
}
listGround.empty();
I get a compile error saying that there is no user-defined-conversion operator available that can perform this conversion etc etc on the line that is marked FAIL in the above code.
If I use a std::shared_ptr
everything works as intended. Same goes for raw pointers.
Why am I getting this error?
error C2664: 'void std::vector<_Ty>::push_back(std::unique_ptr &&)' : cannot convert parameter 1 from 'std::unique_ptr<_Ty>' to 'std::unique_ptr<_Ty> &&' 1> with 1> [ 1>
_Ty=std::unique_ptr 1> ] 1> and 1> [ 1> _Ty=Dirt 1> ] 1> and 1> [ 1> _Ty=Ground 1> ] 1> Reason: cannot convert from 'std::unique_ptr<_Ty>' to 'std::unique_ptr<_Ty>' 1>
with 1> [ 1> _Ty=Dirt 1> ] 1>
and 1> [ 1> _Ty=Ground 1> ] 1>
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
Upvotes: 3
Views: 1084
Reputation: 9770
std::vector::push_back
requires the type passed to be copyable (or in C++11 movable) and std::unique_ptr
is not copyable. That's what the error message is telling you that it is missing the corresponding conversion for moving. You can move a std::unique_ptr
by using the std::move
function which simply does the appropriate cast to the right r-reference type.
Upvotes: 1
Reputation: 179809
Create the thing in place:
listGround.emplace_back(new Dirt());
It's not a shared_ptr
, yet you try to have ownership shared between dirt
and listGround.back()
Upvotes: 1