c++stdvectormove-semantics

Static assertion failed: result type must be constructible from input type when moving objects into std::vector


I'm experimenting with move semantics in C++, and I have a simple class Entity that should only be movable — copying is disabled.

Here’s the class:

class Entity {
public:
     //...
    Entity() = delete;
    Entity(const Entity& entity) = delete;
    explicit Entity(Mesh&& mesh) : mesh(std::move(mesh)) {
        printf("Entity Created");
    }
    Entity(Entity&& entity) noexcept: mesh(std::move(entity.mesh)) {
        printf("Inside the Entity move Constructor");
    }

    //...
private:
    Mesh mesh;
};

And here’s how I’m trying to use it:

//...
Entity e1(std::move(mesh_1));
Entity e2(std::move(mesh_2));

std::vector<Entity> entities = {std::move(e1), std::move(e2)};
//...

This line causes the following error:

error: static assertion failed: result type must be constructible from input type

Why is this happening?


Solution

  • The issue with

    std::vector<Entity> entities = {std::move(e1), std::move(e2)};
    

    is that {std::move(e1), std::move(e2)} creates a std::initializer_list<Entity> and the elements of said list are all marked as const. This means that after you move e1 and e2 into the list, the vector needs to make a copy since you can't move a const object.

    In this case, since you have a deleted copy constructor, you get an error as there is no way to get the elements from the list into the vector.