代码之家  ›  专栏  ›  技术社区  ›  Goswin von Brederlow

如何在适当的位置创建+填充容器?

  •  2
  • Goswin von Brederlow  · 技术社区  · 6 年前

    我正在尝试创建一个不能复制或移动的类数组。所以我需要在适当的地方创建对象,我不知道如何做到这一点:

    #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;
    };
    

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

    3 回复  |  直到 6 年前
        1
  •  5
  •   NathanOliver    6 年前

    你可以使用 std::vector s迭代器对构造函数来构造

    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;
    };
    
        2
  •  2
  •   Maxim Egorushkin    6 年前

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

    Bla(const std::vector<int> & args) 
        : foo(args.begin(), args.end())
    {}
    
        3
  •  1
  •   Hiroki    6 年前

    对于最一般的情况,难道没有什么方法可以从向量参数和lambda中创建初始值设定项列表吗?

    创建STL容器的另一种方法 Foo 无法复制或移动的包含 std::unique_ptr<Foo> 可移动。 例如,作为更一般的情况,如果 int double 分别是,然后是 Bla 为您工作:

    DEMO

    #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;
    };