如何就地创建+填充容器?
How to create + fill a container in-place?
我正在尝试创建一个无法复制或移动的 类 数组。所以我需要就地创建对象,但我不知道该怎么做:
#include <vector>
struct Foo {
Foo(int) { }
Foo(const Foo &) = delete;
Foo & operator =(const Foo &) = delete;
Foo(Foo &&) = delete;
Foo & operator =(Foo &&) = delete;
};
struct Bla {
Bla(const std::vector<int> & args) {
for (auto i : args) {
foo.emplace_back(i);
}
}
std::vector<Foo> foo;
};
编译器抱怨删除的移动构造函数,因为它不能保证所有对象都是就地构造的并且从不移动。我不必使用 std::vector
作为容器,所以请随意提出其他建议。
一种方法是使用范围构造函数。当传递随机访问迭代器时,它不会重新分配向量:
Bla(const std::vector<int> & args)
: foo(args.begin(), args.end())
{}
您可以使用std::vector
的迭代器对构造函数来构造像
这样的对象
Bla(const std::vector<int> & args)
: foo(args.begin(), args.end())
{}
如果您有额外的参数需要包含在构造中,那么您可以切换到任何基于节点的容器,例如 std::list
struct Bla {
Bla(const std::vector<int> & args) {
for (auto i : args) {
foo.emplace_back(i, some_other_argument);
}
}
std::list<Foo> foo;
};
For the most generic case isn't there some way to make an initializer list from the vector args and a lambda?
创建无法复制或移动的 Foo
的 STL 容器的另一种方法是包含可移动的 std::unique_ptr<Foo>
。
例如,作为更一般的情况,如果 Foo
的构造函数的第一个和第二个参数分别是 int
和 double
,那么下面的 Bla
适合你:
#include <tuple>
#include <vector>
#include <memory>
struct Bla
{
Bla(const std::vector<std::tuple<int, double>>& args)
{
foo.reserve(args.size());
for (const auto& i : args) {
foo.push_back(
std::make_unique<Foo>(std::get<0>(i), std::get<1>(i)));
}
}
std::vector<std::unique_ptr<Foo>> foo;
};
我正在尝试创建一个无法复制或移动的 类 数组。所以我需要就地创建对象,但我不知道该怎么做:
#include <vector>
struct Foo {
Foo(int) { }
Foo(const Foo &) = delete;
Foo & operator =(const Foo &) = delete;
Foo(Foo &&) = delete;
Foo & operator =(Foo &&) = delete;
};
struct Bla {
Bla(const std::vector<int> & args) {
for (auto i : args) {
foo.emplace_back(i);
}
}
std::vector<Foo> foo;
};
编译器抱怨删除的移动构造函数,因为它不能保证所有对象都是就地构造的并且从不移动。我不必使用 std::vector
作为容器,所以请随意提出其他建议。
一种方法是使用范围构造函数。当传递随机访问迭代器时,它不会重新分配向量:
Bla(const std::vector<int> & args)
: foo(args.begin(), args.end())
{}
您可以使用std::vector
的迭代器对构造函数来构造像
Bla(const std::vector<int> & args)
: foo(args.begin(), args.end())
{}
如果您有额外的参数需要包含在构造中,那么您可以切换到任何基于节点的容器,例如 std::list
struct Bla {
Bla(const std::vector<int> & args) {
for (auto i : args) {
foo.emplace_back(i, some_other_argument);
}
}
std::list<Foo> foo;
};
For the most generic case isn't there some way to make an initializer list from the vector args and a lambda?
创建无法复制或移动的 Foo
的 STL 容器的另一种方法是包含可移动的 std::unique_ptr<Foo>
。
例如,作为更一般的情况,如果 Foo
的构造函数的第一个和第二个参数分别是 int
和 double
,那么下面的 Bla
适合你:
#include <tuple>
#include <vector>
#include <memory>
struct Bla
{
Bla(const std::vector<std::tuple<int, double>>& args)
{
foo.reserve(args.size());
for (const auto& i : args) {
foo.push_back(
std::make_unique<Foo>(std::get<0>(i), std::get<1>(i)));
}
}
std::vector<std::unique_ptr<Foo>> foo;
};