I need a map to a polymorphic set of objects, which requires a map to pointers to avoid slicing. Since I would like the life-cycle of the value-objects to be tied to that of the map object, I would like to use unique_ptr
.
This leads me to the following construction:
#include <memory>
#include <string>
#include <map>
#include <vector>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() {};
};
struct Square : public Shape {
double a;
Square(double a) { this->a = a; };
double area() const { return a*a; };
};
typedef std::map<std::string, std::unique_ptr<Shape>> ShapeMap;
// Creating an instance of ShapeMap with a factory is ok:
ShapeMap buildShapeMap() {
ShapeMap m;
m.emplace("square1", std::make_unique<Square>(2));
return m;
}
ShapeMap m1 = buildShapeMap();
But, what I would really like to do is a static constructor:
/* Fails: std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)': attempting to reference a deleted function
ShapeMap m2{
{ "square1", std::make_unique<Square>(2) }
};
*/
I assume the move semantics are somehow different here -- but is it something I can get around, or should I just stick with the factory-approach?
As a followup question: Should I expect similar issues in the following?
struct World {
std::string name;
ShapeMap shapes;
World(std::string const &name, ShapeMap &shapes) : name(name), shapes{ shapes } {
};
};
World world1{
ShapeMap{
{ "square2", std::make_unique<Square>(3) }
}
};