c++stdvectoremplaceaggregate-type

Emplace an aggregate in std::vector


I tried to initialize the std::vector

std::vector<Particle> particles;

with instances of the simple struct

struct Particle {
    int id;
    double x;
    double y;
    double theta;
    double weight;
};

by using emplace with an initializer list:

num_particles = 1000;
for (int i = 0; i < num_particles; i++)
{
    particles.emplace_back({ i,0.0,0.0,0.0,1 });
}

But I get the error

C2660 "std::vector>::emplace_back": Function doesn't accept one argument

How can I fix that?


Solution

  • std::vector::emplace expects an iterator as argument too, because it inserts the element before that iterator's position.

    Another problem is that your {i, 0.0, 0.0, 1} initialization doesn't work because it isn't in a context which tells what type it needs to instantiate. The reason there isn't any context is due to emplace and emplace_back member functions having generic parameters.

    If you just want to append elements to the vector, use emplace_back.

    However, emplace_back depends on the element type having a valid constructor in order to work, as the element is initialized through parentheses. That changed in C++20, which now allows aggregate-initialization through parentheses without the need to define a valid constructor.

    So, up until C++17, your example would be changed to:

    for (int i = 0; i < num_particles; ++i)
        particles.push_back({i, 0.0, 0.0, 1});
    

    And in C++20 and later, you may do this instead:

    for (int i = 0; i < num_particles; ++i)
        particles.emplace_back(i, 0.0, 0.0, 1);