简体   繁体   English

在 std::vector 中放置一个聚合

[英]Emplace an aggregate in std::vector

I tried to initialize the std::vector我试图初始化 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:通过将 emplace 与初始化列表一起使用:

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 C2660“std::vector>::emplace_back”:函数不接受一个参数

How can I fix that?我该如何解决?

You have several issues with your code:您的代码有几个问题:

  • Emplace takes an iterator as insertion point, and then a list of values which serve as arguments to a constructor. Emplace 将迭代器作为插入点,然后是作为构造函数参数的值列表。

  • Your struct must have a constructor which takes the values you pass to emplace.你的结构必须有一个构造函数,它接受你传递给 emplace 的值。

  • You only have 4 argument values in your code, but your Particle struct has 5 fields.您的代码中只有 4 个参数值,但您的Particle结构有 5 个字段。

Try this code instead:试试这个代码:

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

    Particle(int id, double x, double y, double theta, double weight) 
        : id(id), x(x), y(y), theta(theta), weight(weight)
    {
    }
};

Notice the constructor there.注意那里的构造函数。 And then emplace, for instance in the beginning [just an example which is not inserting at the back (see below)]:然后放置,例如在开头[只是一个没有插入后面的例子(见下文)]:

std::vector<Particle> particles;

auto num_particles = 1000;
for (int i = 0; i < num_particles; i++)
{
    particles.emplace(particles.begin(), i, 0.0, 0.0, 1.0, 0.0);
}

As others have noted, if you just want to insert without specifying a specific position in the vector, you can use emplace_back :正如其他人所指出的,如果您只想插入而不指定向量中的特定位置,则可以使用emplace_back

std::vector<Particle> particles;

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

This inserts the elements at the end of the vector.这会在向量的末尾插入元素。

std::vector::emplace expects an iterator as argument too, because it inserts the element before that iterator's position. std::vector::emplace需要一个迭代器作为参数,因为它在迭代器的位置之前插入元素。

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.另一个问题是您的{i, 0.0, 0.0, 1}初始化不起作用,因为它不在一个说明它需要实例化什么类型的上下文中。 The reason there isn't any context is due to emplace and emplace_back member functions having generic parameters.其理由没有任何上下文是由于emplaceemplace_back具有通用参数的成员函数。

If you just want to append elements to the vector, use emplace_back .如果您只想将元素附加到向量,请使用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.但是, emplace_back取决于具有有效构造函数的元素类型才能工作,因为元素是通过括号初始化的。 That changed in C++20, which now allows aggregate-initialization through parentheses without the need to define a valid constructor.这在 C++20 中发生了变化,现在允许通过括号进行聚合初始化,而无需定义有效的构造函数。

So, up until C++17, your example would be changed to:因此,在 C++17 之前,您的示例将更改为:

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:在 C++20 及更高版本中,您可以改为这样做:

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

First, std::vector::emplace requires the first argument passed to be an iterator representing the position where the element should be inserted.首先, std::vector::emplace要求传递的第一个参数是一个迭代器,表示应该插入元素的位置。

Secondly, even if you provide the position.其次,即使你提供了职位。 Template types are not deduced for initializer_lists .不会为initializer_lists推导出模板类型。 See initializer_list and template type deduction .参见initializer_list 和模板类型推导 So, below will equally fail :所以,下面同样会失败

particles.emplace( particles.end(), {i, 0.0, 0.0, 1, 1});

Since there is no constructor that can take the initializer list, below will likewise fail :由于没有可以获取初始化列表的构造函数,下面同样会失败

particles.emplace( particles.end(), i, 0.0, 0.0, 1, 1);

You either use insert or push_back as in:您可以使用insertpush_back如下所示:

particles.insert( particles.end(), {i, 0.0, 0.0, 1, 1});
particles.push_back({i, 0.0, 0.0, 1, 1});

or emplace or push_back:或 emplace 或 push_back:

particles.emplace( particles.end(), Particles{i, 0.0, 0.0, 1, 1});
particles.emplace_back(Particles{i, 0.0, 0.0, 1, 1});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM