C++ 如何创建+;把一个容器装满?

C++ 如何创建+;把一个容器装满?,c++,in-place,C++,In Place,我试图创建一个不能复制或移动的类数组。因此,我需要在适当的位置创建对象,但我不知道如何做到这一点: #include <vector> struct Foo { Foo(int) { } Foo(const Foo &) = delete; Foo & operator =(const Foo &) = delete; Foo(Foo &&) = delete; Foo & operator =(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;
};
#包括
结构Foo{
Foo(int){}
Foo(const Foo&)=删除;
Foo&运算符=(const Foo&)=删除;
Foo(Foo&&)=删除;
Foo&运算符=(Foo&&)=删除;
};
结构Bla{
Bla(常量标准::向量和参数){
用于(自动i:args){
foo.安置(i);;
}
}
std::矢量foo;
};

编译器抱怨删除的move构造函数,因为它不能保证所有对象都在适当的位置构造并且从不移动。我不必使用std::vector作为容器,所以请随意提出其他建议。

一种方法是使用范围构造函数。当传递随机访问迭代器时,它不会重新分配向量:

Bla(const std::vector<int> & args) 
    : foo(args.begin(), args.end())
{}
Bla(const std::vector和args)
:foo(args.begin(),args.end())
{}

您可以使用
std::vector
s迭代器对构造函数来构造如下对象

Bla(const std::vector<int> & args) 
    : foo(args.begin(), args.end())
{}
对于最常见的情况,是否有某种方法可以从向量args和lambda生成初始值设定项列表

创建不能复制或移动的
Foo
STL容器的另一种方法是包含可移动的
std::unique_ptr
。 例如,作为更一般的情况,如果
Foo
的ctor的第一个和第二个参数分别是
int
double
,则以下
Bla
适用于您:

#包括
#包括
#包括
结构Bla
{
Bla(常量标准::向量和参数)
{
foo.reserve(args.size());
用于(常量自动&i:args){
把你推回去(
std::使_唯一(std::get(i),std::get(i));
}
}
std::矢量foo;
};

如果向量调整大小,则必须移动或复制元素。当您第一次为所有元素保留足够的空间时,它是否起作用?确切的编译器错误是什么?
void Bla(const std::vector&args)
->
Bla(const std::vector&args):foo(args.begin(),args.end()){}
?当然,我的保留建议不会有帮助。如果有一个
emplace\u no\u reserve\u more
,保证在容量小于新容量时不会进行任何重新分配和抛出,那就太酷了size@AlgirdasPreidžius我猜它起作用的原因是构造器提前知道大小,可以先保留并在适当的位置构造元素,因此,不需要重新分配,也不需要移动任何元素,尽管这只是一个猜测,但仍然不足以满足需求answer@AlgirdasPreidžius
std::距离(开始,结束)
对不起,我的问题太简单了。所以Answare不够通用。如果Foo接受了一个对所有对象都相同的附加参数,比如Foo(args[i],extra),该怎么办?@GoswinvonBrederlow我想你应该为此添加新的问题。这个答案回答了原始问题i.m.o.@GoswinvonBrederlow在这种情况下,您需要您的类是可移动的,并使用迭代器适配器。谢谢。关于使用基于节点的容器的技巧为我解决了这个问题。第一个(迭代器对构造函数)依赖于从
int
Foo
的隐式转换构造函数,它只在问题中的简化代码中起作用。std::列表将适用于我的用例。@GoswinvonBrederlow没有问题。如果您确实需要随机访问,您可以使用第一个示例,它只需要大量的管道,您必须更改
Foo
的构造函数,以获取包含所有参数的单个容器,而不是单独获取每个参数。@GoswinvonBrederlow如果您对列表满意,那么您也可以使用智能指针向量
struct Bla {
  Bla(const std::vector<int> & args) {
    for (auto i : args) {
      foo.emplace_back(i, some_other_argument);
    }
  }
  std::list<Foo> foo;
};
#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;
};