初始化std :: array而不复制/移动元素

时间:2017-02-09 16:36:27

标签: c++ c++11 initialization copy-constructor stdarray

#include <iostream>
#include <string>
#include <array>

class C {
private:
    std::string a;
    std::string b;
    std::string c;
public:
    C(std::string a_, std::string b_, std::string c_) : a{a_},b{b_},c{c_} {}
    ~C(){};
    C(const C&) =delete;
    C(const C&&) =delete;
    const C& operator=(const C&) =delete;
    const C& operator=(const C&&) =delete;
};

std::array<C,2> array = {C("","",""),C("","","")};

int main()
{}

这不会编译(带有NDK和clang的Android Studio),并且&#34;调用已删除的c&#34;构造函数。错误。我知道我可以,例如使用std::vectoremplace_back()直接在容器内部构造元素,但在我的代码中,我只想使用固定大小的容器和不可复制/可移动的对象进行优化。我可能在这里缺少基本的,但是没有办法初始化std::array而不必首先构建单个元素然后将它们复制到那里?

2 个答案:

答案 0 :(得分:7)

您可以使用大括号括起初始值设定项代替临时c对象:

std::array<c,2> array = {{{"",""},{"",""}}};

std::array<c,2> array{{{"",""},{"",""}}};

答案 1 :(得分:6)

从C ++ 17开始,对于某些特定情况copy elision,可以保证这一点。

  

在下列情况下,编制者需要省略   类对象的复制和移动构造函数,即使复制/移动也是如此   构造函数和析构函数具有可观察到的副作用:

     
      
  • 在初始化中,如果初始化表达式是prvalue,并且源类型的cv-nonqualified版本与   目的地的类,初始化表达式用于   初始化目标对象:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x
    
  •   

对于这些情况,不需要访问复制/移动构造函数。

  

When copy-elision takes place (until C++17) In those cases where copy-elision is not guaranteed, if it takes place (since C++17)和   复制/移动构造函数未被调用,它必须存在并且   可访问的(好像根本没有发生优化),否则   节目形成不良。

LIVE