Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initialize std::array without copying/moving elements

#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()
{}

this won't compile (Android Studio with NDK and clang) with a "call to deleted constructor of c" error. I know that I can e.g. use a std::vector and emplace_back() to construct an element directly inside the container, but in my code I want to only use fixed-sized containers and non-copyable/moveable objects for optimization. I'm probably missing sth basic here, but isn't there a way to initialize the std::array without first having to construct the individual elements and then copy them there?

like image 482
Marinos K Avatar asked Feb 09 '17 16:02

Marinos K


2 Answers

You can use brace enclosed initializers instead of temporary c objects:

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

or

std::array<c,2> array{{{"",""},{"",""}}};
like image 124
juanchopanza Avatar answered Nov 06 '22 14:11

juanchopanza


It would become possible since C++17, from that for some specified cases copy elision is guaranteed.

Under the following circumstances, the compilers are required to omit the copy- and move- constructors of class objects even if copy/move constructor and the destructor have observable side-effects:

  • In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:

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

And for these cases, copy/move constructor is not required to be accessible.

When copy-elision takes place (until C++17) In those cases where copy-elision is not guaranteed, if it takes place (since C++17) and the copy-/move-constructor is not called, it must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed.

LIVE

like image 30
songyuanyao Avatar answered Nov 06 '22 14:11

songyuanyao